3 ms·
So you want to gradually reduce the fidelity of the error message as it makes its way up the stack. That means that the top level handler can at best log a vag
by barrkel 11mo ago
So you want to gradually reduce the fidelity of the error message as it makes its way up the stack.
That means that the top level handler can at best log a vague message.
That in turn means you must log along the way where you have more precise information about the failure, or you risk not having enough information to fix issues.
And that in turn means you must have lots of redundant logging, since each point in the stack doesn't know whether the abstraction it's invoking has already logged or not, or encapsulation would be violated.
- 1718627440 11mo ago> That in turn means you must log along the way where you have more precise information about the failure Yes, that's the idea. You split the information into a diagnostic with stuff you deal with now and data that the upper layer will handle. The intersection between the data in these two things should be empty. > And that in turn means you must have lots of redundant logging, since each point in the stack doesn't know whether the abstraction it's invoking has already logged or not, or encapsulation would be violated. No. You print a diagnostic, about what exactly THIS layer was trying to do, you don't speculate what the upper layer was trying to do and try to log that. Every layer knows the lower layer has already logged the primary error, because an error object exists, and it also knows that the upper layer will print a diagnostic about what was the intention, so it only prints exactly what the error was in this layer. > doesn't know whether the abstraction it's invoking has already logged or not, or encapsulation would be violated. It knows that the lower layer has logged all stuff that that layer considered to be important, and that none of the data that is available to this layer was logged, since that is the responsibility of the caller. An example: Document rendering incomplete, skipped publishing step. Thumbnail #39 missing. Failed to fetch image: Connection refused. [Discarded malformed packet with SYN flag. Invalid data in src/network/tcp.c:894 parse_tcp_packet_quirks_mode] Depending on the log level, you wouldn't show the later diagnostics. If there is a debug flag set, you can also add the function/line information to every step, not just to the last. If you are outtputing to stuff like syslog, you would put each diagnostic on its own line.
- barrkel 11mo agoThe problem with this is you don't have context on subgraphs of control flow which have already returned by the time of the error. I think our disagreement is less about error handling and more about logging policy. I favour a logging policy which lets you understand what the code is doing even if it doesn't error out; this means that you don't need to log on unwind. You favour a logging policy specific for errors. My position is that your position ends up with less useful context for diagnosing errors.
- 1718627440 11mo agoThere is no reason you can use that scheme only for errors? In fact I don't. I use "unwinding" for diagnostics even in the happy case.
- rerdavies 11mo agoOr you can use chained error messages. Unable to create the media database. Failed to upgrade the database from version 3 to version 6. SQL Query failed. Syntax error at column 29 near "wehre". ("SELECT id`Thumbnail from tThumbailIndex wehre idFile=?"). (Messages are pre-pended to inner errors as one progresses up the stack). Yes, a gruesome error message. But it's a gruesome error condition. I've also used inner exceptions in a large Enterprise product, and was very pleased with the result. (Java has them, .net has them, C++ and Typescript can have them if you want them). At the top level, the error message goes: Unable to connect to the media database. Failed to upgrade from version 3 to version 6. SQL Query error failed. Syntax error at column 6 near 'ndex. ("SELECT idI'ndex from T_ThumbnailIndex") (each successive error message contained in a successive inner exception). The advantage: no need to assemble multiple lines of logged errors from a logfile that end-users really don't want to be digging around in. A more prosaic and actually end-user-helpful chained message might be: Unable to connect to the media database. Failed to create the file /var/MediaServer/mediaIndex.db Out of disk space.