PurelyFunctional.tv Newsletter 444: Humane models of errors

Sign up for weekly Clojure tips, software design, and a Clojure coding challenge.

Issue 444 - September 27, 2021 · Archives · Subscribe

Design Idea 💡

Human models of errors

For the last two issues, I've been talking about ideas for making programming more humane. Yes, decomposing a system into fine-grained parts helps create a better system. But pre-composing them up in practical ways for a human programmer/user can go a long way to making a system more humane. One area that is ripe for re-modeling is errors.

The current state of the art seems to be for the system to punt errors up to the caller. In the best cases, the error object contains a good, human-readable explanation of what has gone wrong and enough data to understand the details. For instance, if you try to read a file and it doesn't exist, the error should tell you that it couldn't find the file and at least tell you what file it's talking about. That little bit of context can help to debug tremendously. It's very frustrating what a language says, "I was expecting an Int, and you passed a String," but it doesn't tell you what String it was.

But even good error messages only help you diagnose the problem. A human-level error system should handle errors much more gracefully. Many errors should never be reported as problems to the user because they could be handled automatically. Take a problem I face when uploading a video to YouTube as I do for my podcast. I use the YouTube API so I can script the upload process. It can take an hour or two to upload the 4GB video files. About one time in ten, the upload fails, and my script exits incomplete.

Yes, I can (and probably should, now that I think about it) write a more intelligent script. But it shows what we could build into the system. I cannot be the only one whose uploads fail and who wants them to retry automatically. Many operations should not be retried on failure. How would it know the retry was safe to do? The answer is that we need to model it in the errors.

What should we model? The short answer is anything we need to make it more declarative. I want to say, "put my video on YouTube." I don't want to manage API calls. Here are some

  • Is the error safe to ignore?
  • Is the action retriable? And on what schedule?
  • Is there an alternative action to try next?
  • What was the context of the error?
  • Is there some information that is needed but missing, like login credentials?
  • If I can't recover from the error, what should happen now?

Of course, not all of these are appropriate in a script I run at the command line. But if we're talking about a whole humane programming system, the UI could help the user interact with the errors and decide what to do. And I contend that if the system were more humane, I would enjoy interacting with it.

Podcast episodes🎙

I think there are two episodes since I last mentioned them.

Apropos Episode 📽️

Another one in the can! We're working on our new website in Clojure. All code, all the time! Watch here. Please join the Discord server so you can watch live!

Deep thoughts 🤔

I was recently looking through clojure.lang.Reflector.java and it struck me how much work it must have been to get the interoperation between Clojure and Java to work so smoothly. There are so many weird cases that I would not have thought of at all. Thanks to Rich Hickey for all that work.

Pandemic update 😷

I know a lot of people are going through tougher times than I am. If you, for any reason, can't afford my courses, and you think the courses will help you, please hit reply and I will set you up. It's a small gesture I can make, but it might help.

I don't want to shame you or anybody that we should be using this time to work on our skills. The number one priority is your health and safety. I know I haven't been able to work very much, let alone learn some new skill. But if learning Clojure is important to you, and you can't afford it, just hit reply and I'll set you up. Keeping busy can keep us sane.

Stay healthy. Wash your hands. Wear a mask. Get vaccinated if you can. Take care of loved ones.

Clojure Challenge 🤔

No challenge last issue

This week's challenge

Bigram checker

A bigram is a sequence of two letters. Common bigrams in English include st and tr. Write a function to check if all bigrams in a collection are present in the words in a string.

Examples

(all-present? ["st" "tr"] "street") ;=> true
(all-present? ["ea" "ng" "kt"] "eating at a restaurant") ;=> false
(all-present? [] "hello!") ;=> true

Thanks to this site for the problem idea, where it is rated Hard in Ruby. The problem has been modified.

Please submit your solutions as comments on this gist.

Rock on!
Eric Normand