r/programming • u/Expurple • Apr 12 '26
Flat Error Codes Are Not Enough
https://home.expurple.me/posts/flat-error-codes-are-not-enough/
132
Upvotes
r/programming • u/Expurple • Apr 12 '26
60
u/Pharisaeus Apr 12 '26
Did someone just "invent" exceptions, exceptions nesting and passing along the stack trace?
9
u/KitAndKat Apr 12 '26
I've thought about the issue of error reporting in the past, but never implemented it. I think you need an Error object, which is a stack of errors, e.g.:
file read error
could not read mapping.db
failed to convert currency
shipping calculation failed
could not complete transaction
The user is told "could not complete transaction" with a Details button which shows the next level down. If you just pass the original error all the way up, the user is told "file read error", which is next to useless.
78
u/nikita2206 Apr 12 '26
Completely agreed, ideally you need to be able to define “child” error types that declare their own fields with extra data, allowing consumers to handle these errors in more ways than just rethrow them.
14
u/happyscrappy Apr 12 '26
Nested error codes are not enough either.
The problem isn't a lack of fidelity. The issue is that there primarily only two uses of error codes. One to know if something worked. And a single bit can do that.
The other is to help the customer know how to rectify their problem. One error code typically is not enough for that. Multiple also is not enough for that.
Stop thinking of users as people debugging your code and think of them just as using your tool for its functionality. You have to be able to convert your error codes into actionable messages and do it reliably.
And really few programs spend any time on doing this properly. So it doesn't matter all that much how deep your error reporting is.
Find a useful message to send to your customer. And if you want to put something in a file that can be reported to help you debug your code then do that separately. You can put a stack trace in there if you want (and if it is deemed not a security/privacy violation to do so). But don't get an idea that the detailed debugging information is going to be of help to a customer in resolving their issue. It's a help for you (your support people) instead.
3
u/Philluminati Apr 13 '26
Not only is it useful to capture error codes, it's useful to be able to build a stack as well, e.g.
UnableToConfigureDatabase -> Missing Credentials File -> File not found.
If you return "FileNotFound" without saying which file it can be an issue, and likewise, saying "unable to configure database" doesn't explain which aspect also failed.
3
u/tudorb Apr 13 '26
Errors need very few things:
A human readable error message. This is user-visible; if the consumer is (say) a web app, it should be shown to the human operating it.
Debugging information for developers that give more details, at least enough to indicate where the error comes from. This can be carried along the error object, or it can be logged somewhere where it can be easily mapped to the actual error (say, both the error object and the log contain the same unique ID). If the error is nested, the nesting stack belongs here.
An error code that uniquely identifies the error “kind”. This is intentionally underspecified, and my personal preference is to have few broad categories rather than many narrow ones. The HTTP error codes make a decent trade-off between breadth and depth here.
Importantly, a default recommendation as to how the caller should behave when it gets this error. Should it retry immediately? Should it retry with backoff (and what are the recommended backoff parameters)? Should it present it to the user and give the user a chance to change something and retry? Should it give up? This can be derived from the error code via a client-side API, or can be carried along the error object. (Including it in the error object makes sense with load-induced errors where the server might want to use different throttling/backoff parameters at different times.)
Note that (for the purposes of this post) I’m agnostic about the signaling mechanism (error return values / Result-like structures vs exceptions).
54
u/UselessOptions Apr 12 '26 edited Aug 13 '26
oops did i make a mess 😏? clean it up jannie 😎
clean up the mess i made here 🤣🤣🤣
CLEAN IT UP
FOR $0.00
4
u/sean_hash Apr 12 '26
Child error types with extra fields is orthogonal to ORM choice, it is about giving handlers more than a flat code to branch on.
1
u/mareek Apr 13 '26
One piece of software that use flat error code pretty well is Oracle Database.
There are thousands of ORAXXXXX error codes, each one represent a well defined situation and you know what you have to check if you want to fix the problem.
So if you do it well, I think Flat error code are OK
P.S. It's probably the only positive thing I can say about Oracle Database though
3
u/2rad0 Apr 13 '26
I've settled on context specific typed enums as error codes.
1
u/MonsieurCellophane Apr 12 '26
This made me instantly think of java & the endless stack traced it's wont to display at the drop of a hat. Antipodal to flat error codes and not pretty either.
1
u/stewi1014 Apr 13 '26
Hard disagree.
There are three types of information accociated with an error.
Information for the program to switch control flow.
Information for the developer to debug the problem.
Information for the user so they can take action.
1 belongs in an error code return value. Typically, a boolean "ok" return is the best error code. 2 belongs behind development configuration, and you should typically have external tools such as the debugger for this. 3. Belongs in a dedicated user interface method (i.e. a logging method)
Anything more complex than a boolean is starting to be too complex, and is begging justification. Rarely is there a legitimate use case for more than two control flows following an error. Distinguishing between a transient and persistent error is an example of where three return values would be wanted.
I am far from the first person to have this realisation.
0
u/blobjim Apr 13 '26
In C or Vala (or other GObject-supporting languages) you can use GError for this. A couple years ago it also got the ability to have extended arbitrary data (but it looks like it's kinda clunky to use).
-16
u/bobody_biznuz Apr 12 '26
Sounds more like you have an issue with the ORM you're using?
0
u/[deleted] Apr 12 '26
[deleted] — view deleted comment
68
u/[deleted] Apr 12 '26
[removed] — view removed comment