In PLT Scheme, the procedure error raises the exception exn:fail, which contains an error string. There is no "implicit catch" for all defines. Look at the following sample:
;; test.ss
(define (a d)
(printf "~a~n" (/ 10 d)))
(a 0) ;; The interpreter will exit here.
(printf "OK~n")
Execute the above script from the command line and you will see the interpreter existing after printing something like
/: division by zero
=== context ===
/home/user/test.ss:1:0: a
If an exception is not handled within the user program, it is propagated up to the core interpreter where a default handler deals with it, i.e print the exception and exit. In other words, the interpreter just says, "an exception was raised and I don't know how to deal with it, so I am quiting". This is not much different from how the JVM or some other virtual machine handle exceptions.
To learn more about PLT Scheme's exception handling mechanism, please read about with-handlers and dynamic-wind in the MzScheme Language Manual. Using these, you can even emulate Java's try-catch-finally block.
(define (d a b)
(try
(printf "~a~n" (/ a b))
(catch (lambda (ex)
(printf "Error: ~a" ex)))
(finally
(if (> b -2)
(d a (sub1 b))))))
Here is the syntax extension that made the above possible:
;; try-catch-finally on top of with-handlers and dynamic-wind.
(define-syntax try
(syntax-rules (catch finally)
((_ try-body ... (catch catch-proc))
(with-handlers (((lambda (ex) #t)
(lambda (ex)
(catch-proc ex))))
(begin
try-body ...)))
((_ try-body ... (catch catch-proc) (finally fin-body ...))
(dynamic-wind
(lambda () ())
(lambda ()
(with-handlers (((lambda (ex) #t)
(lambda (ex)
(catch-proc ex))))
(begin
try-body ...)))
(lambda () fin-body ...)))
((_ try-body ... (finally fin-body ...))
(dynamic-wind
(lambda () ())
(lambda () try-body ...)
(lambda () fin-body ...)))))