This idea can also be explored in the Go programming language. Go has an error type, not exceptions, but error checking famously can be rather verbose. Two cases to consider come to mind. First, the common pattern result, err := SomeFunc() if err != nil { return err } Here the code is just passing along the error to the caller, unchanged. Second, signaling errors ab initio result := // some calculation or behavior if…
IME, returning a "stringly-typed" error is only wrong if you don't provide enough context in the returned error message. You can describe what you were doing as an error message and pass it back up the stack, each layer adding their own context, ie what they were trying to do to what. At the top you (should) get a pretty complete picture of what went wrong and why. I have found this reasonable and proportionate for m…
Code Design Decision – Always throw custom exceptions
51–60 of 92 posts
Re: Code Design Decision – Always throw custom exceptions
#52In short: if you have a meaningful recovery pathway for a particular exception this can be useful, but I found that 9 out of 10 exceptions/errors in code cannot be recovered from. This is checked exceptions all over again... Frankly, I usually do exactly the opposite. Most cases I've seen the exceptions that can arise are not widely known in advance, and for most spots where exceptions can be raised from I simply do…
> If my DB is not accessible - do I really, really need to wrap it? I would say yes. Most of your code doesn't care that the database failed with a PG-300292-AB error. What you do care about is that there is a system failure. If you wrap your system failure, and document it as THE exception, the API caller will know what to look for. In general there really are only a few exceptions: system, invalid input, non found.…
Re: Code Design Decision – Always throw custom exceptions
#53Earlier quoted context omitted.
I think there are two kinds of exceptions in languages that have them as their error handling mechanism. 1. Exceptions you expect your consumers to handle. 2. Exceptions you don't expect your consumers to handle. The first one I would argue you should wrap third party exceptions. There is in nearly every case important context in your code that the thrower of the third party exception will not know and whoever is rea…
"Exceptions you expect the consumer to handle" should be explicit return values on the function signature instead, via an Either/Result type or similar. Unless you're writing Java where you can force certain exception types to be handled, but people never write that code properly.
Re: Code Design Decision – Always throw custom exceptions
#54Earlier quoted context omitted.
That is true, so the library should throw the checked exception, and if the caller has no way to handle it, it should wrap the checked exception in an unchecked exception and throw the unchecked exception. Not too hard, and library clients that can handle some checked exceptions will be able to. I hate libraries that only throw unchecked exceptions. It seems easier initially, but makes writing correct code more diffi…
> If the caller has no way to handle it, it should wrap the checked exception in an unchecked exception and throw the unchecked exception. Not you have a new problem: How is the code calling the caller supposed to know about that exception? You can't even catch it (even if you know about it!) using normal try-catch because what you have to do is catch the wrapper exception and then check inside that for the exception…
If the complaint is that you then have too many different unchecked exceptions perhaps the error domain has been improperly modeled and you are getting a clue that the system is poorly designed.
Re: Code Design Decision – Always throw custom exceptions
#55Earlier quoted context omitted.
> Just because it's useful to wrap exceptions in 5% of the cases doesn't mean you should wrap the rest 95% just in case. YAGNI. I'm going to curse here, but ... fucking seriously. If I get a .net ADO exception coming out of a 3rd party library it's absolutely not going to shock me or throw me for a loop. But do you know what IS a pain in the ass? Using 3 different libraries, all that wrap that same ADO exception in t…
What do you use libraries for if not for the abstraction layer?
Re: Code Design Decision – Always throw custom exceptions
#56Earlier quoted context omitted.
"Exceptions you expect the consumer to handle" should be explicit return values on the function signature instead, via an Either/Result type or similar. Unless you're writing Java where you can force certain exception types to be handled, but people never write that code properly.
Very few languages actually support Either or Result types ergonomically. I don't have a problem with people using exceptions for these but I do think if the language has compile time type checking it should provide a distinction between checked exceptions and non checked exceptions. I am very much in the minority here but I find it very useful to let robots tell me I forgot something than to discover I forgot it in…
Re: Code Design Decision – Always throw custom exceptions
#57Earlier quoted context omitted.
This is one of the problems with checked exceptions. The library author is in no position to expect me to handle an exception. Whether or not I can relies on the design of my system, which they have no window into.
This is the problem of Java's implementation of checked exceptions... because they are not generic. Which forces middle layers to make impossible decisions like this. If the type system were more capable, they'd just be equivalent to typed generic error returns, which work fine.
Re: Code Design Decision – Always throw custom exceptions
#58Just because it's useful to wrap exceptions in 5% of the cases doesn't mean you should wrap the rest 95% just in case . YAGNI. 1. You don't know which exceptions will be raised in advance. Anything that involves IO can fail in a plethora of ways, and you don't even know which calls involve IO (e.g. a library might choose to cache something on disk). 2. Consumers of your code will not know how to deal with those excep…
I thought the point of exceptions was what we're now calling observability.
If somehow wrapping them in your own goo because you, the dev of that code, can help diagnose problems, more power to you.
But most of the time that doesn't really help so letting them bubble up and not obscuring root causes is better.
So . . . Use judgement. If you don't have judgement, ask a friend. If you don't have a friend, just let the exceptions propagate on their own.
Re: Code Design Decision – Always throw custom exceptions
#59Earlier quoted context omitted.
> Just because it's useful to wrap exceptions in 5% of the cases doesn't mean you should wrap the rest 95% just in case. YAGNI. I'm going to curse here, but ... fucking seriously. If I get a .net ADO exception coming out of a 3rd party library it's absolutely not going to shock me or throw me for a loop. But do you know what IS a pain in the ass? Using 3 different libraries, all that wrap that same ADO exception in t…
Haha, that's actually a good point. A single problem can affect dozens of modules, each having a different wrapper. If my db goes down, I very much prefer to see a single DatabaseConnectionFailed than a multitude of FailedToSaveObject, DatabaseError, CannotLoadData, IOError, SomethingIsWrongThisShouldNeverHappen, DBHostUnavailable all over the place. Good luck navigating through the noise and isolating those.
Re: Code Design Decision – Always throw custom exceptions
#60but this is far nicer way of saying the same thing https://ericlippert.com/2008/09/10/vexing-exceptions/
I actually do not think your code should throw exceptions. It is really just an Either / result and then if something does blow its because you havent anticipated it via wrapping something in an either or result ... and so it should blow and the callers of your library should be submitting a defect..