[plt-scheme] Re: exception handling
On May 16, wooks wrote:
>
> Don't understand the explanation in the docs. Looks complicated and
> what I want to do is real simple. Ignore the exception and carry on.
(with-handlers ([(lambda (exn) #t) (lambda (exn) 'whatever)])
(* 3 "4"))
> Don't understand why I need with-handlers since I don't want to do
> anything with the exception.
`with-handlers' allows you to catch the exception and do whatever you
want with it -- you don't have to actually use it, like the above.
But see what I said in the other message -- since it catches all
errors, it will catch errors in your own code too. A common mistake
is to try to use it, for example, to remove a temporary file where
nothing bad happens if it's not removed. Using the above:
> (define (delete-files files)
(for-each delete-file files))
> (define (delete-temp-files)
(with-handlers ([(lambda (exn) #t) (lambda (exn) 'whatever)])
(delete-files "foo.txt" "bar.txt" "baz.txt")))
> (delete-temp-files)
whatever
Looks fine right? Well, following my advice in the previous email,
I should make the `with-handlers' as specific as possible. In this
case, I should really ignore only `exn:fail:filesystem?' exceptions.
If I do that, then I'd find that I had a real bug in the code:
> (define (delete-files files)
(for-each delete-file files))
> (define (delete-temp-files)
(with-handlers ([exn:fail:filesystem? (lambda (exn) 'whatever)])
(delete-files "foo.txt" "bar.txt" "baz.txt")))
> (delete-temp-files)
procedure delete-files: expects 1 argument, given 3: "foo.txt"
"bar.txt" "baz.txt"
The other thing that I said is good is to put the with-handlers around
as little code as possible -- in this case, this would mean moving it
to the `delete-files' function, or even around each file deletion:
> (define (delete-files files)
(for ([file files])
(with-handlers ([exn:fail:filesystem? (lambda (exn) 'whatever)])
(delete-file file))))
This would also avoid masking out my real bug, since
`delete-temp-files' doesn't ignore errors in its body.
Even better is to not ignore the exception; for example, this code
will report the error, but will continue to run:
(list
1
(with-handlers ([exn? (lambda (exn)
((error-display-handler) (exn-message exn) exn)
'whatever)])
(* 2 "3"))
4)
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://www.barzilay.org/ Maze is Life!