X-Git-Url: https://jxself.org/git/?p=8sync.git;a=blobdiff_plain;f=eightsync%2Fagenda.scm;h=edade135c09499e7b08beaf86c573c01d5fb3e1e;hp=a965a2c6d3b50fff9a86567145bd5d5ac4b6ebeb;hb=fbb1776a35db50db19fc158381e74361d6e9b789;hpb=496f85495101750b469bd2b30b37db0ba02aca7f diff --git a/eightsync/agenda.scm b/eightsync/agenda.scm index a965a2c..edade13 100644 --- a/eightsync/agenda.scm +++ b/eightsync/agenda.scm @@ -65,6 +65,8 @@ %port-request %run %run-at %run-delay + catch-8sync catch-%8sync + print-error-and-continue %current-agenda @@ -444,8 +446,9 @@ Will produce (0 . 0) instead of a negative number, if needed." "Run BODY asynchronously at a prompt, passing args to make-future. Runs things asynchronously (8synchronously?)" - (abort-to-prompt (current-agenda-prompt) - async-request)) + (propagate-%async-exceptions + (abort-to-prompt (current-agenda-prompt) + async-request))) ;; Async port request and run-request meta-requests (define (make-async-request proc) @@ -467,11 +470,20 @@ return the wrong thing via (%8sync) and trip themselves up." async-request)))) (define-record-type - (make-wrapped-exception key args stack) + (make-wrapped-exception key args stacks) wrapped-exception? (key wrapped-exception-key) (args wrapped-exception-args) - (stack wrapped-exception-stack)) + (stacks wrapped-exception-stacks)) + +(define-syntax-rule (propagate-%async-exceptions body) + (let ((body-result body)) + (if (wrapped-exception? body-result) + (throw '%8sync-caught-error + (wrapped-exception-key body-result) + (wrapped-exception-args body-result) + (wrapped-exception-stacks body-result)) + body-result))) (define-syntax-rule (%run body ...) (%run-at body ... #f)) @@ -492,16 +504,28 @@ return the wrong thing via (%8sync) and trip themselves up." ;; like evaluating immediately. Is that what we want? (kont ;; Any unhandled errors are caught - (catch #t - ;; Run the actual code the user requested - (lambda () - body ...) - ;; If something bad happened and we didn't catch it, - ;; we'll wrap it up in such a way that the continuation - ;; can address it - (lambda (key . args) - (make-wrapped-exception key args - (make-stack #t 1 0)))))) + (let ((exception-stack #f)) + (catch #t + ;; Run the actual code the user requested + (lambda () + body ...) + ;; If something bad happened and we didn't catch it, + ;; we'll wrap it up in such a way that the continuation + ;; can address it + ;; @@: For this stack to work doesn't it have to be + (lambda (key . args) + (cond + ((eq? key '%8sync-caught-error) + (match args + ((orig-key orig-args orig-stacks) + (make-wrapped-exception + orig-key orig-args + (cons exception-stack orig-stacks))))) + (else + (make-wrapped-exception key args + (list exception-stack))))) + (lambda _ + (set! exception-stack (make-stack #t 1 0))))))) when)))) (define-syntax-rule (%run-delay body ... delay-time) @@ -521,6 +545,22 @@ return the wrong thing via (%8sync) and trip themselves up." (lambda () body ...))))) +(define-syntax-rule (catch-8sync exp (handler-key handler) ...) + (catch '%8sync-caught-error + (lambda () + exp) + (lambda (_ orig-key orig-args orig-stacks) + (cond + ((or (eq? handler-key #t) + (eq? orig-key handler-key)) + (apply handler orig-stacks orig-args)) ... + (else (raise '%8sync-caught-error + orig-key orig-args orig-stacks)))))) + +;; Alias...? +(define-syntax-rule (catch-%8sync rest ...) + (catch-8sync rest ...)) + ;;; Execution of agenda, and current agenda