3 ms·
> 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 abo
by azov 15y ago
> 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_Initialization http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initial...) you get a free ride. Otherwise you have to write non-trivial cleanup code regardless of how you return errors. Try/catch (and especially finally) helps a lot because you get to group all your cleanup in one place. With error codes the code looks something like:
a = acquire(A)
if (!a) return
b = acquire(B)
if (!b) {
release(a)
return
}
c = acquire(C)
if (!c) {
release(a)
release(b)
return
}
...
This is a maintenance nightmare. It's hard to see what the code is doing because the real logic is hidden between piles of error handling stuff. If you add a new resource acquisition in the middle you have to go over every statement that follows and modify error handlers. And don't you dare changing the order of statements, because that basically forces you to rewrite the whole function. Believe me, you don't want this in your code, exceptions are your friend :)
- regularfry 15y agoNo, 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.
- gue5t 15y agoConsider: 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;