adjust the way internal errors are shown in DrRacket
so that printing an error no longer blocks (on user actions) but still uses the GUI. Also: when new errors are generated while a dialog box showing an error is still open, then just ignore those errors. Also, if an error is generated that has been shown in the last 5 minutes, ignore the new one.
This commit is contained in:
parent
4763fb5189
commit
0e543fc66b
|
@ -31,24 +31,65 @@
|
|||
|
||||
(define system-security-guard (current-security-guard))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;
|
||||
;; internal error display support
|
||||
;;
|
||||
|
||||
(define error-display-chan (make-channel))
|
||||
(thread
|
||||
(λ ()
|
||||
(define-struct recent (msg when))
|
||||
(define currently-visible-chan (make-channel))
|
||||
(let loop ([recently-seen-errors/unfiltered '()]
|
||||
[currently-visible #f])
|
||||
(sync
|
||||
(handle-evt
|
||||
error-display-chan
|
||||
(λ (msg+exn)
|
||||
(define recently-seen-errors
|
||||
;; recent errors are ones less than 5 minutes old
|
||||
(let ([now (current-seconds)])
|
||||
(filter (λ (x) (<= (+ (recent-when x) (* 60 5)) now))
|
||||
recently-seen-errors/unfiltered)))
|
||||
(define-values (msg exn) (apply values msg+exn))
|
||||
(cond
|
||||
[currently-visible
|
||||
;; drop errors when we have one waiting to be clicked on
|
||||
(loop recently-seen-errors #t)]
|
||||
[(ormap (λ (x) (equal? msg (recent-msg x)))
|
||||
recently-seen-errors)
|
||||
;; drop the error if we've seen it recently
|
||||
(loop recently-seen-errors #f)]
|
||||
[else
|
||||
;; show the error
|
||||
(define title (error-display-handler-message-box-title))
|
||||
(define text (let ([p (open-output-string)])
|
||||
(parameterize ([current-error-port p]
|
||||
[current-output-port p])
|
||||
(original-error-display-handler msg exn))
|
||||
(get-output-string p)))
|
||||
|
||||
(parameterize ([current-eventspace error-display-eventspace]
|
||||
[current-custodian system-custodian])
|
||||
(thread
|
||||
(λ ()
|
||||
(message-box title text #f '(stop ok) #:dialog-mixin frame:focus-table-mixin)
|
||||
(channel-put currently-visible #f))))
|
||||
(loop (cons (make-recent msg (current-seconds)) recently-seen-errors)
|
||||
#t)])))
|
||||
(handle-evt
|
||||
currently-visible-chan
|
||||
(λ (val)
|
||||
(loop recently-seen-errors/unfiltered #f)))))))
|
||||
|
||||
;; override error-display-handler to duplicate the error
|
||||
;; message in both the standard place (as defined by the
|
||||
;; current error-display-handler) and in a message box
|
||||
;; identifying the error as a drscheme internal error.
|
||||
(error-display-handler
|
||||
(λ (msg exn)
|
||||
|
||||
;; this may raise an exception if the port is gone.
|
||||
(with-handlers ([exn:fail? (λ (x) (void))])
|
||||
(original-error-display-handler msg exn))
|
||||
|
||||
(let ([title (error-display-handler-message-box-title)])
|
||||
(let ([text (let ([p (open-output-string)])
|
||||
(parameterize ([current-error-port p]
|
||||
[current-output-port p])
|
||||
(original-error-display-handler msg exn))
|
||||
(get-output-string p))])
|
||||
|
||||
(parameterize ([current-custodian system-custodian])
|
||||
(parameterize ([current-eventspace error-display-eventspace])
|
||||
(message-box title text #f '(stop ok) #:dialog-mixin frame:focus-table-mixin)))))))
|
||||
(channel-put error-display-chan (list msg exn))))
|
||||
|
|
Loading…
Reference in New Issue
Block a user