Ivory for Mastodon for macOS

May 23rd, 2023

Ivory

I just downloaded the Ivory for macOS app from the App Store, and upgraded my subscription to the Universal Subscription, so that it would cover all my devices. It's just an amazing app. This iOS/iPadOS version has been working really well for me since it was released, and now that I have the macOS version, I'll not have to worry about Ice Cubes and reading two streams.

I don't know that Mastodon will ever be popular enough to have some of the feeds from Twitter on it, but that's OK... I'm at about 95% complete, and I don't really need the last 5%. Plus, you just can't beat that it's not under the thumb of a capricious individual.

All in all... a nice bit of news for today. 🙂

Interesting Issues with Clearbit

April 24th, 2023

Alarm icon

This weekend we had an interesting issue with Clearbit's Logo Search interface - a free service they provide on their Business Information Service system. You can basically hit their endpoint with a query param of the name of a Company, and they will respond with something that looks like:

  {
    name: 'Flexbase',
    domain: 'flexbase.app',
    logo: 'https://logo.clearbit.com/flexbase.app'
  }

which is a nice little thumbnail logos of the Company. It's a very nice tool, and for the most part works flawlessly.

Until it doesn't.

The real issue was the Open Source Node client that was hitting the company's endpoint. It started with:

  topSuggestion(name){
    return new Promise((resolve, reject) => {
      resolve(getTopSuggestion(name));
    });
  }

which called:

  let getTopSuggestion = (query) => {
    return new Promise((resolve, reject) => {
      request(config.api.autocomplete + '?query=' + query, (err, response, body) => {
        resolve(JSON.parse(body)[0]);
      });
    });
  }

Now when everything is working as it should, this code is just fine. But on the weekend, the response from the endpoint in getTopSuggestion() was returning:

  Welcome to the Company API. For docs see https://clearbit.com/docs#company-api

which, of course, isn't JSON, and so the JSON.parse() was throwing an exception. But the function getTopSuggestion() was using the resolve() for the Promise, so it was creating an exception that could not be caught. This was bad news.

Now as it turned out, a coworker found that Clearbit was doing some maintenance, and that might have been the genesis of the issue, but it was made much worse because when we debugged this on our machines - several of us, the issue didn't present itself. Only in production.

Still, it was clear this wasn't the right code to use, and the library was 6 years old without an update, and the code was small. So a coworker suggested we just make the one call ourselves:

    let res = {}
    try {
      // Get the top URL Suggestion for a store name
      const url = new URL(config.api.autocomplete)
      url.searchParams.append('query', name)
      // ...now make the call, and parse the JSON payload
      const payload = await fetch(url).then(response => response.json())
      if (Array.isArray(payload) && payload.length > 0) {
        // ...pick off the top suggestion
        res = payload[0]
      }
    } catch (err) {
      log.error(`[logoFinder] ...message... Name: '${name}', Details: "${err.message}"`)
      return {
        success: false,
        error: errorMessages.badClearBitRequest,
        exception: err,
      }
    }
    return {
      success: true,
      ...res,
    }
  }

where the error message is really up to you, but the point was that this was something that would handle the simple text being returned by the endpoint and throw the exception on the JSON parsing without causing all the trouble of the library we were using.

There were a few things I liked about the new implementation we came up with:

  • Explicitly setting the query param on the URL - while it's possible that 90% of all name values would not lead to an issue, it's always nice to be safe and make sure that the proper encodings are done with the query params. It's two lines of code, but it makes sure that it's all handled properly.
  • The chaining of fetch() and then() - both fetch() and response.json() are async functions, so you might expect to see two await prependers on the functions, but there's only one. This is a nice feature of the then(), in that it unrolls the async nature of the fetch() so that the async nature of the .json() comes through - returning the value to the caller.

Sure, we still need to get the first element in the Array, but we also test that to make sure it's actually an array, and that there's something to get. It's just a lot more defensive coding than the original client had, and when we did this, we still got the good results on the dev machines, and at the same time, we got proper exception catching on the production instances.

Thankfully, the issues resided about the time we got the fix into the code, tested, and into production, so it wasn't long-lived, but it was a problem for a while, and we were able to recover the errors due to queues and retries, which is another saving grace that I was very thankful for.

Nothing like a little production outage to make the day exciting. 🙂

It’s been a Wild Month

March 28th, 2023

WallSt.jpg

Over the course of the last few weeks, we've seen the collapse of Silicon Valley Bank, and Signature Bank, and the Feds stepping in to reassure the depositors that everything will be OK, every deposit will be made whole, and the only losses will be to the stock holders of SVB. It's something that they didn't have to do, by regulation, but they did to return confidence to the smaller banks, and keep the deposits from being moved to the top-10 banks, and cause a real problem in all the smaller banks.

Still, it's faded from the headlines, and while The Journal is still covering it, it's not USA Today anymore, and that means that the bulk of the crisis is over - that of the lack of confidence in the system. People are no longer concerned, and that's really very good news.

The job market is still a mess... and it's going to take the financial markets to stabilize and start to head up, for the job market to return. It's confidence that drives good hires, not desperation. Still, this is just another cycle, and we'll weather it.

There are better days ahead. 🙂

Trip to the Dentist

February 28th, 2023

Path

Today is another trip to the dentist, and while I'm getting to the point that I can pretty much deal with these things, I won't be sorry when I don't have to. I know they mean well, and I know it's childhood trauma, but it's also the experience you have with the dentist, and therein lies a tale.

Today is two weeks after a procedure that was performed with such brutality, it set me back at least a decade in my comfort level with the dentist. It was a new guy, and he was brutal... just brutal. But it was done, and I counted my blessings that it was done. Now I have to go back for a post-op check, and get the stitches removed. I'm not looking forward to it.

I know it'll be over, and that's what I have to look forward towards, because thinking about what happened two weeks ago is mighty painful. But I'll survive.

Ivory for Mastodon by Tapbots

January 30th, 2023

Ivory

With the Early Release of Ivory by Tapbots, I think I've found the clear winner for a Mastodon client. This is very good - and it's got a lot more work that they want to do on it... so it's only going to get better.

Right now, it's got everything I used on Twitter, plus other nice features that are part of Mastodon natively. All in all, it's actually a nice upgrade.

I would still like to see the local town alerts (weather, service interruptions, etc.) come to Mastodon, but even if they don't, it's far better than whatever Twitter is turning into.

Moved to Mastodon

January 20th, 2023

Mastodon

With the recent demise of the Twitter API for third-party clients, it was time to move to Mastodon, all I really needed was a little push from a friend, and then off we went. I will say, the native client isn't bad, and Tapbots is creating Ivory, which sounds promising, but I'm pretty pleased with Ice Cubes - an Open Source Mastodon client using SwiftUI, available on the App Store. It's not bad at all on iPad, and on iOS it's really very nice.

I still will be very interested in seeing what Ivory looks like - as I really want one client that syncs on all my devices - as Twitterrific did, and I know the Tapbots guys will make that happen. But we'll see... who knows, given that it's SwiftUI, it's possible to imagine that Ice Cubes will be on macOS too... Could be interesting.

In any case, it was the people... the community, that made Twitter nice, and they're moving, and the place won't be worth a tenth of the purchase price in a few months.

Twitterrific is Silent

January 14th, 2023

Twitterrific.jpg

This morning, Twitterrific for iOS had problems logging in, and at first, I thought it was the 2FA I had applied to my account after a friend's account was hacked. The token on my iPhone expired, and I needed to re-authenticate my account with the 2FA, and yet when I tried to do that... nothing.

It was an hour later that I was still trying to find out what it might be, when I saw the news that Twitter had simply revoted the access tokens for some of the third-party iOS clients - while leaving the macOS clients alone. For example, Twitterrific for macOS is fine. This wasn't a mistake - it was intentional, and that's a shame. They chose to do this, and it's their company, so OK... but I can't imagine this standing - or maybe it's the beginning of the end?

I guess I'll see what Mastodon is all about...

Happy Birthday to Me!

December 31st, 2022

Cake.jpg

Another year in the books, and another year for me. As a kid, my birthday was way too close to Christmas, but as I've gotten older, it's nice to have them close together. I don't have to worry about people making a fuss on my birthday, and I can be assured that most everyone will be thinking about, and making plans for, their New Year's Eve activities, and so don't really think much about me. It's almost like stealth birthday - which is just fine with me.

Today, I'm heading down to Indy to visit my siblings, and just enjoy the day. I'll be back later, and that's OK. I've got The Talk Show to listen to on the way down and back - and Gruber is without a doubt, one of the more entertaining talk show personalities to me. It's always a good listen. So on my birthday I get to have good food, good company, and something good to listen to.

I am so very grateful for it all.

Merry Christmas!

December 25th, 2022

Christmas Tree

It's another amazing Christmas, and all is quiet. Quiet times... noisy times... it's all a wonderful time of year to spend time with family and friends and enjoy the Season. It's time to enjoy a nice movie, or maybe a football game, and to have some special treats that you don't normally have - all to remember the traditions you grew up with.

Today I'll just be relaxing and enjoying the quiet. It's Sunday, so I'll send out my weekly texts to family and friends, and then sit back and enjoy the quiet of the day. It's just my favorite time of year. 🙂

Big Update Morning

December 14th, 2022

Yosemite

This morning has been a Big Update morning to be sure... iOS 16.2, tvOS 16.2, iPadOS 16.2, and macOS 13.1 all ready to go from Apple, and so everything I had went through the update. It's nice to get things up to date, not just because some of the things I've seen in Safari on macOS and iPadOS are iffy... but it's a chance to get some little surprises as well.

One thing that I've read about that I didn't really like is the new What's Up on tvOS... it used to be the things in my list, and now it's almost advertising for the things that some folks think I might be interested in. Not a huge fan, and would love to have a way to get back to the way it was. We'll see...

Until then, things are humming along, and it's nice to get it all done in an early morning. 🙂