3 ms·
> The nonsense end result of that line of logic is that you return a single boolean that corresponds to failure/success, so I assume that's not what you mean.
by MaulingMonkey 4y ago
> The nonsense end result of that line of logic is that you return a single boolean that corresponds to failure/success, so I assume that's not what you mean.
I frequently find that is all that is necessary, and is exactly the correct solution, not "nonsense" whatsoever. Perhaps even that boolean is overkill: an unrecoverable bug should perhaps instead log and then terminate, producing no error condition for the caller of your library to worry about attempting to recover from whatsoever. Detailed error reporting can be done without obscenely distinct error types, and in fact detailed error reporting frequently benefits from a focus on the task itself instead of trying to structure data to leave the task of actually reporting the error to someone else, and kicking the can down the road.
E.g. for parsing focused errors like this I'd be more interested in pretty printing the source line in question, underlining the error, etc. - I wrote https://github.com/MaulingMonkey/json-spanned-value https://github.com/MaulingMonkey/json-spanned-value for helping ease the display of bad JSON data in a manner that integrates with your IDE for ease of fixing said data by jumping directly to the cause.
And then, admittedly, there are times when different errors should be recovered from differently. When the caller might wish to retry an operation after some errors, try a different operation after other, report file+line+range information for yet other errors, etc. - these have very concrete answers to "What do you expect the user of your library to do with this detailed information?" that are not difficult to answer at all.
> Contrast the two error messages:
Both are UTF8 strings without types adding anything obviously useful. A silly demo screenshot of errors that will open the offending document if closed, and navigate to the line/column of said error:
https://github.com/MaulingMonkey/json-spanned-value/blob/master/examples/demo.png https://github.com/MaulingMonkey/json-spanned-value/blob/mas...
Which operates by immediately dumping the "errors" to terminal without any error types involved whatsoever... nor even a boolean branch! Well, a real program might set a boolean so the CLI knows to exit(1) instead of using partially parsed data...
- jsmith45 3y ago> an unrecoverable bug should perhaps instead log and then terminate For an application, sure that can be fine. One needs to be careful in a library, because it is not always the case that what seems like an unrecoverable error to the library author is always unrecoverable for the application. Consider a library designed to retrieve process information from "/proc". I could very easily see a library author concluding that if "/proc" does not exists that is an unrecoverable error worthy of termination. After all, in that case, the library is useless. The application that wants to use the library may strongly disagree, and may be expecting that /proc might be unavailable in some locked down environment in which it sometimes runs, and has some fallback it can use in those environments. If you return a error the application can easily fallback. Otherwise you are forcing the application to do something like check for /proc existing before even calling your library. A library with global state may assume that if some invariant of that global state fails to hold (and this got detected) that this should be treated as unrecoverable. And well this one can also vary. Sometimes having the process die here can be the right approach, especially for certain development scenarios, since this means there is either a code bug, nasty undefined behavior, or possibly a compiler bug going on. But depending on the nature of the library it might be possible that there is a sensible way to reset things without bad side effects, in which case, it could potentially make sense to return an error indication that the application could potentially handle by unwinding to a state where resetting your library is sensible, and then resetting it.
- shepmaster 4y ago> Which operates by immediately dumping the "errors" to terminal without any error types involved whatsoever I haven't looked at your code, but if I take this sentence at face value, I'd be very hesitant to use your library in many contexts. One example would be anything similar to a web server, such as an API that accepts JSON via a HTTP POST. It would be very strange to have my JSON parser print to the console where no one is reading! A lot of your comment indicates similar focus on a human interacting with a terminal, which is a very valid usecase, but not the only usecase. > instead of trying to structure data to leave the task of actually reporting the error to someone else, and kicking the can down the road. I agree with this in broad strokes. I think that it's very important to use your error types to ensure that they provide value. For the JSON example, I think that I might have an error that indicates the specific error as well as a byte offset that the error occurred. This could be built on by higher level errors that convert to line/column numbers or attach an excerpt of the bad input, as appropriate. These types could have methods or implement traits that allow formatting for the console (considering optional coloring, etc.) or be formatted for a logging system. > an unrecoverable bug should perhaps instead log and then terminate I technically agree, but I have a very high bar for when a library I write is allowed to unilaterally terminate the process — it's simply too drastic of a decision to make in most cases. I also hope that the act of logging is appropriately abstracted. Thankfully, Rust only has a few common logging interfaces so it's easy to fall into the pit of success there.