Earlier quoted context omitted.
I'm sorry, but this is a very bad example. iptables had an issue for a long time where error code is not carefully preserved in many situations and you end up with messages like: iptables: Unknown error 4294967295 This wouldn't happen with exceptions - even if not handled properly, you'd see where is it originating and what's the most probable cause of the issue. And it's not necessarily iptable's fault - in some cas…
Return the first one. You always care more about the original error than an explanation of why you failed in cleaning up after it.
Isaacs: try/catch is an anti-pattern
121–130 of 140 posts
Re: Isaacs: try/catch is an anti-pattern
#122Earlier quoted context omitted.
> I can decide to make something in my code exceptional, sure. I can't decide to make something in the library not-exceptional, though. Making something in the library non-exceptional is equivalent to discarding an error. Catch the exception and discard it. Done. Do this at whatever level you feel is appropriate (or don't, and handle the exception in a more reasonable fashion). > In other words, somebody thought it w…
Making something in the library non-exceptional is equivalent to discarding an error ... The other option seems to be to continue in a erroneous state. I guess this is where we differ. I feel that the designers of the .NET library have chosen to throw exceptions in places where nothing exceptional is actually happening, where no error has occurred, where the programmer may very well be expecting the "exceptional" out…
When does this actually happen? Are you really expecting it to fail when you open a file, or when you parse an integer, or whatever else? Where is .Net throwing exceptions in cases that no error has occurred and that you expect?
This complaint is common, but it feels rather hollow to me. Most of the time it seems to come down to a preference for error codes over exceptions, or an annoyance with the try-catch boilerplate, rather than a legitimate complaint about exceptions being thrown inappropriately.
> Where my code must handle such conditions, forcing me to handle them as exceptions makes my code longer, less readable, harder to change, and harder to reason about.
Are you suggesting that every function should have two versions like Parse and TryParse? Is this really what you'd prefer the .Net team work on, instead of providing new tools and functionality? Or are you wanting something like "ON ERROR RESUME NEXT" so that you can ignore these "expected" errors?
> This is exactly what the author of the linked piece points out, this is a part of my complaint, and it's an issue Microsoft has tacitly acknowledged the seriousness of by the addition of alternatives to exception-throwing calls, like TryParse().
Eh, the linked piece seemed mostly to be pining for the days of error codes. There's no general way to determine if a failure is a "bug" or "expected", not for exceptions and not for anything else. If you want to avoid exceptions for "expected" failures, then you're asking for no exceptions at all, which is fine, but the problem isn't just the definition of "exceptional".
> It does not feel to me, as a user of these massive libraries, that there was any systematic way of deciding what should be and what should not be reported as an exception.
The systematic way was "it's exceptional if it's not the desired or expected outcome". The addition of TryParse was a nice bonus, but is in itself an exception to the exception model.
Re: Isaacs: try/catch is an anti-pattern
#123Earlier quoted context omitted.
> when we had to check the return/value and or the error code after every function call... if we wanted error handling to work. Errors as return values force you to think about every possible error, which is a good thing for code quality. Look at how much rock stable C software we have out there. Software that can be compiled on many different architectures, run in many different environments, and it all just works,…
In a modern programming environment you can't think about every possible error. In particular, code often migrates into distributed systems where a whole new range of problems can happen. For instance, a system might have plug-ins that get data from a CSV file, a relational database and a web service. One day somebody comes along and adds a plug-in that gets data from a noSQL database. Add a new component to the syst…
In fact, I think you can argue that keeping error-handling local to the call site (return codes) encapsulates and abstracts the errors better than letting an exception propagate arbitrarily far up the stack.
Exceptions are decision-free, but not making a decision (propagating an exception without handling it) doesn't make you any more robust to the vagaries of the modern world, it just moves the problem somewhere else.
Now, if multiple children in a call graph can experience the same error, and should be dealt with in exactly the same way, then propagating an exception up to a common ancestor in the call graph makes your code simpler. The fact that the compiler writes that dumb plumbing code for you is a great argument for exceptions, but not all applications fit the use case of:
* Same error can manifest itself in many places
* Each instance of the error can be dealt with in a similar-enough way to make a common exception handler simpler than handling errors at each call site.
Edit: Oh, did you mean that if you don't intend to handle an error, exceptions crash your program (good) rather than let it continue silently and do something you don't expect (bad)? If so, good point, and my apologies for the misunderstanding :)Re: Isaacs: try/catch is an anti-pattern
#124Earlier quoted context omitted.
Return the first one. You always care more about the original error than an explanation of why you failed in cleaning up after it.
Counterexample: you failed parsing some number correctly, but the backend where you log broken transactions is corrupted and cannot be written to. You'd rather drop the second information?
Fair enough, you'd rather (as a human being) have the second one. As a matter of building the system, I would still return the first one.
Basically, the second information is important in the sense that you really want an audit trail, but unimportant in that it doesn't tell you why your call failed. Returning it to the caller is useless compared to returning the first error.
But yes, it should certainly be logged and potentially acted on. An application can't do anything useful with the information, but an ops guy can.
So return the first one.
Re: Isaacs: try/catch is an anti-pattern
#125Earlier quoted context omitted.
*BSD kernels, GCC, tar, gzip, ...
BSD kernels have had numerous exploits over the years. GCC is a massive hairball. gzip has had exploits ( http://www.kb.cert.org/vuls/id/381508 for one). Care to try again?
Re: Isaacs: try/catch is an anti-pattern
#126> I much prefer php's json_decode function, since it just returns `null` on invalid input. A function which has the same result in case of an error as when given valid input (hint: 'null' is a valid json string) is neither good design, nor something I would actually 'prefer'. Aside of that (and more to the point of the original article), I do believe that exceptions can be very useful the deeper the abstraction of yo…
I thought a JSON document had to have either a top level object or array, which would make a bare null an invalid JSON text. Granted, we might not be that strict all the time. See section 2, paragraph 2: http://www.ietf.org/rfc/rfc4627.txt?number=4627
The particular issue is that the spec refers to "JSON text" (which no one ever uses in practice) as well as "JSON value" which is what everyone expects. The difference being that a "JSON value" is any of the 'bare' types (null, boolean, number, string, object, or array). A quick survey of JSON parsers will show you that most will accept any of these types at the top level. The one notable exception I'm aware of is Ruby's JSON library (the default one? I'm not so hip to the Ruby).
Notably, though, is that the major JavaScript interpreters don't enforce this constraint (Nor do Python or YAJL (kinda) or Erlang (even the ones I didn't write)).
Don't bother asking me about invalid combining characters as \u escapes. You wouldn't like me when I get the rage eyes.
Re: Isaacs: try/catch is an anti-pattern
#127Earlier quoted context omitted.
Making something in the library non-exceptional is equivalent to discarding an error ... The other option seems to be to continue in a erroneous state. I guess this is where we differ. I feel that the designers of the .NET library have chosen to throw exceptions in places where nothing exceptional is actually happening, where no error has occurred, where the programmer may very well be expecting the "exceptional" out…
> I guess this is where we differ. I feel that the designers of the .NET library have chosen to throw exceptions in places where nothing exceptional is actually happening, where no error has occurred, where the programmer may very well be expecting the "exceptional" outcome. When does this actually happen? Are you really expecting it to fail when you open a file, or when you parse an integer, or whatever else? Where…
Oh, for Pete's sake. I'm not learning what I hoped to here, and you've made up your mind.
Re: Isaacs: try/catch is an anti-pattern
#128> I much prefer php's json_decode function, since it just returns `null` on invalid input. A function which has the same result in case of an error as when given valid input (hint: 'null' is a valid json string) is neither good design, nor something I would actually 'prefer'. Aside of that (and more to the point of the original article), I do believe that exceptions can be very useful the deeper the abstraction of yo…
I just don't think that it's worth the cost of capturing a bunch of stack frames for such a common occurrence as "you posted bad data to my web service".
Re: Isaacs: try/catch is an anti-pattern
#129Earlier quoted context omitted.
> JSON.parse is a library function. How can it judge whether the caller can continue or not just because the JSON cannot be parsed? Don't make assumptions about the caller, throw if your library can't continue. > So although try/catch avoids the hassle of checking state after each operation, you pay for it on errors. If your language supports RAII ( http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initial... ) yo…
No, the way to handle that pattern is with nested gotos: a = acquire(A); if (!a) goto err_a; b = acquire(B); if (!b) goto err_b; c = acquire(C); if (!c) goto err_c; do_stuff(a,b,c); err_c: release(b); err_b: release(a); err_a: return; This is precisely why goto is not universally evil.
a = acquire(A);
if (a)
{
b = acquire(B);
if (b)
{
c = acquire(C);
if (c)
{
do_stuff(a,b,c);
}
release(b);
}
release(a);
}
return;Re: Isaacs: try/catch is an anti-pattern
#130Earlier quoted context omitted.
> I guess this is where we differ. I feel that the designers of the .NET library have chosen to throw exceptions in places where nothing exceptional is actually happening, where no error has occurred, where the programmer may very well be expecting the "exceptional" outcome. When does this actually happen? Are you really expecting it to fail when you open a file, or when you parse an integer, or whatever else? Where…
When does this actually happen? Oh, for Pete's sake. I'm not learning what I hoped to here, and you've made up your mind.
Can you give me a practical situation where an exception is thrown despite there not being an error, aside from the canonical Integer.Parse() example? In my experience, that's not the bulk of any practical program, and it's still exceptional from the point of view of the Parse function.
I'd be interested in discussing this, but I'm not really sure what you think would be an improvement. And yes, it's a rather uphill battle if your proposal is to use error codes most of the time. I think that ship already sailed (although there's a strong case for error codes in C++, but that's kind of a special case).