diff --git a/collects/racket/sandbox.rkt b/collects/racket/sandbox.rkt index f9d717f336..624d145a93 100644 --- a/collects/racket/sandbox.rkt +++ b/collects/racket/sandbox.rkt @@ -32,6 +32,7 @@ sandbox-memory-limit sandbox-eval-limits sandbox-eval-handlers + sandbox-propagate-exceptions call-with-trusted-sandbox-configuration evaluator-alive? kill-evaluator @@ -78,6 +79,7 @@ (define sandbox-eval-limits (make-parameter '(30 20))) ; 30sec, 20mb (define sandbox-propagate-breaks (make-parameter #t)) (define sandbox-coverage-enabled (make-parameter #f)) +(define sandbox-propagate-exceptions (make-parameter #t)) (define (call-with-trusted-sandbox-configuration thunk) (parameterize ([sandbox-propagate-breaks #t] @@ -679,6 +681,7 @@ (define user-cust (make-custodian memory-cust)) (define user-cust-box (make-custodian-box user-cust #t)) (define coverage? (sandbox-coverage-enabled)) + (define propagate-exceptions? (sandbox-propagate-exceptions)) (define uncovered #f) (define default-coverage-source-filter #f) (define input-ch (make-channel)) @@ -759,7 +762,13 @@ (when (eof-object? expr) (terminated! 'eof) (channel-put result-ch expr) (user-kill)) (with-handlers ([void (lambda (exn) - (channel-put result-ch (cons 'exn exn)))]) + (if propagate-exceptions? + (channel-put result-ch (cons 'exn exn)) + (begin + (call-with-continuation-prompt + (lambda () + (raise exn))) + (channel-put result-ch (cons 'vals (list (void)))))))]) (define run (if (evaluator-message? expr) (case (evaluator-message-msg expr) diff --git a/collects/scribblings/reference/sandbox.scrbl b/collects/scribblings/reference/sandbox.scrbl index 7147b86690..d045c693be 100644 --- a/collects/scribblings/reference/sandbox.scrbl +++ b/collects/scribblings/reference/sandbox.scrbl @@ -232,13 +232,14 @@ sandboxed code, for example: ] An error will be signaled in such cases. -Evaluation can also be instrumented to track coverage information when -@racket[sandbox-coverage-enabled] is set. Exceptions (both syntax and +If the value of @racket[sandbox-propagate-exceptions] is true (the +default) when the sandbox is created, then exceptions (both syntax and run-time) are propagated as usual to the caller of the evaluation -function (i.e., catch it with @racket[with-handlers]). However, note -that a sandboxed evaluator is convenient for testing, since all -exceptions happen in the same way, so you don't need special code to -catch syntax errors. +function (i.e., catch them with @racket[with-handlers]). If the value +of @racket[sandbox-propagate-exceptions] is @racket[#f] when the +sandbox is created, then uncaught exceptions in a sandbox evaluation +cause the error to be printed to the sandbox's error port, and the +caller of the evaluation receives @|void-const|. Finally, the fact that a sandboxed evaluator accept syntax objects makes it usable as the value for @racket[current-eval], which means @@ -456,6 +457,17 @@ the evaluator (or the break is lost if the evaluator is not used further). The default is @racket[#t].} +@defboolparam[sandbox-propagate-exceptions propagate?]{ + +A parameter that controls how uncaught exceptions during a sandbox +evaluation are treated. When the parameter value is @racket[#t], +then the exception is propagated to the caller of sandbox. +When the parameter value is @racket[#f], the exception message +is printed to the sandbox's error port, and the caller of the +sandbox receives @|void-const| for the evaluation. The default +is @racket[#t].} + + @defparam[sandbox-namespace-specs spec (cons/c (-> namespace?) (listof module-path?))]{ diff --git a/collects/tests/racket/sandbox.rktl b/collects/tests/racket/sandbox.rktl index 80204ae75b..db0da68b9b 100644 --- a/collects/tests/racket/sandbox.rktl +++ b/collects/tests/racket/sandbox.rktl @@ -172,6 +172,15 @@ (make-bytes 500000))))) =err> "out of memor(?:y)")) + ;; check non-propagation of errors + --top-- + (parameterize ([sandbox-propagate-exceptions #f] + [sandbox-error-output 'string]) + (make-base-evaluator! '(void))) + --eval-- + (/ 0) => (void) + --top-- + (regexp-match #rx"^.*?\n" (get-error-output ev)) => '("/: division by zero\n") ;; i/o --top-- (parameterize ([sandbox-input "3\n"] diff --git a/doc/release-notes/racket/HISTORY.txt b/doc/release-notes/racket/HISTORY.txt index 5be595a05f..d83d990d98 100644 --- a/doc/release-notes/racket/HISTORY.txt +++ b/doc/release-notes/racket/HISTORY.txt @@ -3,6 +3,7 @@ Changed the format of error messages Added raise-argument-error, raise-result-error, raise-arguments-error, raise-range-error racket/contract: added procedure-arity-includes/c +racket/sandbox: added sandbox-propagate-exceptions Version 5.3.0.8 Required modules are instantiated in the order that they are required