[racket] Exception not being caught?

From: Gregory Woodhouse (gregwoodhouse at me.com)
Date: Tue Sep 4 13:43:34 EDT 2012

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.)

Posted on the users mailing list.