[racket] Exception not being caught?
This is strange (to me, anyway). I have two modules: grid.rkt which implements a Sudoku grid but provides no graphical representation, and sudoku.rkt which is responsible for handling the GUI. All updates to the board are sent to the grid object (called grid-model here). Now, in my rudimentary user interface (no menus yet), I have two buttons, Load and Save. One can be used to load a game from disk and the other to save a (possibly in-progress) game back to disk.
Now, in sudoku.rkt I define load-button this way
;;Load a puzzle from disk.
(define (load-puzzle! frame model)
(with-handlers ([exn:fail:filesystem? (lambda (exn)
;(message-box "Can't open file" (exn-message exn) frame '(caution))
(printf " The error is: ~a~n" exn)
)])
(let
([the-file (get-file "Please select a puzzle" frame "puzzles" #f #f '() '(("Sudoku" "*.sdk")))])
(send model load-grid! (path->string the-file)))))
(I put the printf in there just to be sure that my use of message-box wasn't the culprit.)
Now, I changed one of my saved games to file permissions 000 to generate an error. When I try to load that file I get the following error (displayed in the interactions window):
> (sudoku)
Cannot open file /Users/gregwoodhouse/sudoku/puzzles/puzzle-4a.sdk
#(struct:exn:fail:filesystem call-with-input-file: cannot open input file
path: /Users/gregwoodhouse/sudoku/puzzles/puzzle-4a.sdk
system error: Permission denied; errno=13 #<continuation-mark-set>)
>
It turns out that load-grid! in grid.rkt has a handler of its own (something I had forgotten), but I don't see any messages from it, either. I don't suppose the details matter, but they're not too long so I'll just include the full method:
(define/public (load-grid! fname)
(with-handlers
((exn:fail:filesystem?
(lambda (exn)
(printf " Cannot open file ~a~n~a~n" fname exn)))
(exn:fail?
(lambda (exn)
(printf "Something went wrong!~n~a~n" exn))))
(let
([ht
(call-with-input-file fname
(lambda (in)
(read in)))])
(let
([x (hash-ref ht 'given)]
[y (hash-ref ht 'user)]
[z (if (hash-has-key? ht 'marks)
(hash-ref ht 'marks)
(make-hasheq))])
(for ([i (hash-keys x)])
(let-values
([(r c) (quotient/remainder i 9)])
(set-given! r c (hash-ref x i))))
(for ([i (hash-keys y)])
(let-values
([(r c) (quotient/remainder i 9)])
(set-cell! r c (hash-ref y i))))
(for ([i (hash-keys z)])
(let-values
([(r c) (quotient/remainder i 9)])
(set-marks! r c (hash-ref z i))))))))
(The file format may seem a bit odd, but I plan to switch from s-expressions to JSON once I get that library figured out.)