I remember reading a paper proposing error handling to be done only at function not block boundaries. A minimal change from the normal exceptions will be something like this:
function foo(bar, quux, zut) try {
var a = frobincate(bar, quux);
return bubinate(a, zut);
} catch (e) {
// Stuff
} finally {
// Stuff
}
Whether such a change will make code easier to write, read and maintain is hard to say. Writing a language that compiles to JavaScript and uses that syntax shouldn't be that hard. I'm partly tempted, but I almost never program in JS
I don't know which paper you read, but C++ supports exactly that syntax. It's rarely seen in the wild as many older compilers didn't implement it and honestly, who wants to remember yet another oddball C++ syntax variation?
I don't think it would be that nice. For good error reports back to the user, you'd have to have a fairly large amount of logic in the catch block. If you have a function that copies data from one file to the other and catch some sort of IOException, you'd end up trying to analyse what it is to report it properly. After all, it could be either one of the files, while opening, closing, reading, writing, ...
_For good error reports back to the user, you'd have to have a fairly large amount of logic in the catch block._
Serious question. How is that a reason to have that _amount of logic_ in the function body?
Having IDE/editors which can fold blocks of code and having the catch blocks collapsed by default will make code reading/understanding of code easier. IMO.
Actually, I may try something like makng the try-cacth the body of the function on a small to medium size project just to see the tradeoffs.
I think that putting it in the body actually reduces the amount of code and makes it more readable. Compare something like this (ignoring naming, formatting, made up language, etc. I want to show the structure only):
fin=open(fin_name)
fout=open(fout_name)
...
catch IOError e
if e.call == 'open'
if e.filename == fin_name
log_error "cannot open input ..."
elif e.filename == fout_name
log_error "cannot open output ..."
else
log_error "cannot open file, but filename unknown"
elif e.call == .....
.....
to something like this:
try
fin = open(fin_name)
catch IOError
log_error "can't open input ...."
return
try
fout = open(fout_name)
catch IOError
fin.close()
log_error "can't open output ...."
return
Both are ugly, but I really wouldn't like to be the person trying to match up the error handling from the first example to the exact places in the function body. I'm not even sure what would this look like if the exception was coming from somewhere deeper in the function. open() is easy because we know how it fails. More complex call chains would be a challenge to even match up to the place they happened.