Wednesday, May 18, 2022

Twisted

The problem most programmers have with error handling is that they tend to think of it as a secondary aspect of their code. They write the code, then they add in the error handling later.

But what if you flip it?

That is, you write the code to collect errors first, and the ‘error condition’ is that the code accidentally worked.

For example, say you are writing a user GUI form. You know that there will be lots of things wrong with the data in the form. So, you set up the form such that each widget has a space for an error message. That it is actually 2 widgets each time, but sometimes that error text is invisible. Then all you need to do is call some overall form validation that will give you the list of these messages that you conditionally stick into the form. Some widgets won’t have errors, but you write the code to assume that most do.

Then inside of the underlying form validation, you iterate through each widget’s input and feed those values to individual validation routines based on some pre-setup form field criteria. If they give you something good, you add it back to the list. If not, that is okay too.

Encoded that way, the logic for handling complex multi-errors in a form is quite simple.

The same is true for any distributed coding. Let's say you have to call a REST API. If you start by assuming that it will fail, then you obviously want to get back a full and detailed set of error information. It can fail for all sorts of reasons, it helps later if you know which specific one caused the fault. That becomes the default behavior.

But sometimes it makes sense, given a few types of the possible errors, that you can just wait and do it again a few seconds later to see if it will work now. You can bury that just below the surface. So, now you have this call that will give you back a detailed error, but occasionally it will wait and retry if it thinks the error might be temporary. If the retries fail, it returns a details error for each attempt.

Then all you need is to encode the ‘error response’ which is that the call worked and it gave you back some clump of data. So in an odd sense, the error is something like OK or Success. After that, you take that clump, and ‘process’ it somehow, then pass that back up the stack.

While this works extremely well for error handling, there are lots of different cases in coding where if you flip your perspective, the code gets simplified. Sometimes even adding fake or ‘virtual’ things works as well, and will really help to clean up the logic. Besides cleaner code, you’ll also find less bugs and the added bonus of being able to visually verify that the code will do what you expect, so you are not as reliant on strong testing.

No comments:

Post a Comment

Thanks for the Feedback!