kazinator 3 hours ago

> Don’t catch fatal exceptions; nothing you can do about them anyway, and trying to generally makes it worse.

Yes there is something: you can design an exception handling system which lets your code specify choices about what to do if such an exception occurs within its contour. Those choices provide ways of passing control to that code.

Then the next layers above the code can decide whether to take those choices, or some other similar choices available from eslewhere, or let the exception bubble up, possibly leaving it unhandled.

The article is a decent tutorial for working with Blub exceptions, but it's limited to that.

tyleo 8 hours ago

I've found that it's hard to instill in teams, "exceptions shouldn't be for user errors."

Perhaps it's an artifact of C#, exceptions are built into the language and sufficient user error handling mechanisms are not. You get some `Try*()` methods but often don't have as much error information as you'd like.

You can mimic Rust's `Result` pattern in C# without much trouble and I've found that to be a good way to go. The biggest downside is the lack of namespace-level typedefs so you always have to include that TError parameter. It's a small price to pay.

Panzerschrek 7 hours ago

Throwing exceptions in out-of-memory cases or something similar has no sense, since no real program can handle such exceptions properly. Throwing exceptions in cases of logic errors (like accessing an array with invalid index) has no sense, since they just conceal bugs. In other cases it's unclear what is exceptional and what is not. So why not just using normal control flow? That's why I personally use no exceptions (I program mostly in C++ and Rust).

  • xg15 12 minutes ago

    > Throwing exceptions in cases of logic errors (like accessing an array with invalid index) has no sense, since they just conceal bugs.

    Catching (and not logging) the exception would conceal the bug, but I wouldn't want to get rid of the stacktrace that comes with throwing the exception - that is extremely useful for narrowing down the location of the bug.

    Incidentally, that's something I've never understood in the "Go style error handling" crowd. The default behavior - if you ignore the return value - in those languages is exactly equivalent to catching and silently throwing away an exception - the thing that's universally understood to be a bad idea. Whereas the default behavior in languages with exceptions is to print the error and exit the program - which us usually seen as the safest choice, unless you have more information and can recover from the exception.

    So if go-style error handling makes it easier to do the bad thing instead of the good thing, why would it still be the superior form of error handling?

lmm 13 hours ago

The classification is probably right, but this post feels half-baked. There are some valuable points in here (never suppress exceptions that indicate programming errors!) but it's missing guidance on how to handle cases like bad user input, and how to actually do the exception handling for cases like file not found.

  • xg15 3 minutes ago

    I don't think there is a lot of guidance you can give in those situations, as the right ways to handle those exceptions are highly context specific. But the point is that you can handle them at all, as opposed to the other types.