fix uncaught-exception-handler handling of non-escaping escape handler
and change the emergency error display handler to log and error Closes PR 11630
This commit is contained in:
parent
0a56e0fc6a
commit
0c193a599a
|
@ -275,17 +275,18 @@ handler that reports both the original and newly raised exception).
|
|||
|
||||
The default uncaught-exception handler prints an error message using
|
||||
the current @tech{error display handler} (see @racket[error-display-handler])
|
||||
and then escapes by calling the current error escape handler (see
|
||||
and then escapes by calling the current @tech{error escape handler} (see
|
||||
@racket[error-escape-handler]). The call to each handler is
|
||||
@racket[parameterize]d to set @racket[error-display-handler] to the
|
||||
default @tech{error display handler}, and it is @racket[parameterize-break]ed
|
||||
to disable breaks. The call to the error escape handler is further
|
||||
to disable breaks. The call to the @tech{error escape handler} is further
|
||||
parameterized to set @racket[error-escape-handler] to the default
|
||||
error escape handler.
|
||||
@tech{error escape handler}; if the @tech{error escape handler} returns, then
|
||||
the default @tech{error escape handler} is called.
|
||||
|
||||
When the current @tech{error display handler} is the default handler, then the
|
||||
error-display call is parameterized to install an emergency error
|
||||
display handler that attempts to print directly to a console and never
|
||||
display handler that logs an error (see @racket[log-error]) and never
|
||||
fails.}
|
||||
|
||||
@defform[(with-handlers ([pred-expr handler-expr] ...)
|
||||
|
|
|
@ -1349,4 +1349,36 @@
|
|||
|
||||
; --------------------
|
||||
|
||||
;; Check that the default uncaught-exception handler falls
|
||||
;; back to the default error escape handler if the current
|
||||
;; one doesn't escape.
|
||||
(test 'done
|
||||
'error-non-escape-handler
|
||||
(begin
|
||||
(call-with-continuation-prompt
|
||||
(lambda ()
|
||||
(parameterize ([error-escape-handler void]
|
||||
[error-display-handler void])
|
||||
(raise 'oops))))
|
||||
'done))
|
||||
|
||||
;; Check that if the current error port is broken,
|
||||
;; so that the default error display handler fails,
|
||||
;; then check that an error is logged.
|
||||
(test #t
|
||||
regexp-match?
|
||||
#rx"output port is closed"
|
||||
(let* ([p (open-output-bytes)]
|
||||
[l (make-logger)]
|
||||
[r (make-log-receiver l 'error)])
|
||||
(close-output-port p)
|
||||
(call-with-continuation-prompt
|
||||
(lambda ()
|
||||
(parameterize ([current-error-port p]
|
||||
[current-logger l])
|
||||
(raise 'ack))))
|
||||
(vector-ref (sync r) 1)))
|
||||
|
||||
; --------------------
|
||||
|
||||
(report-errs)
|
||||
|
|
|
@ -661,23 +661,6 @@ void scheme_init_logger_config() {
|
|||
scheme_set_root_param(MZCONFIG_LOGGER, (Scheme_Object *)scheme_main_logger);
|
||||
}
|
||||
|
||||
static void
|
||||
scheme_inescapeable_error(const char *a, const char *b)
|
||||
{
|
||||
int al, bl;
|
||||
char *t;
|
||||
|
||||
al = strlen(a);
|
||||
bl = strlen(b);
|
||||
t = scheme_malloc_atomic(al + bl + 2);
|
||||
memcpy(t, a, al);
|
||||
memcpy(t + al, b, bl);
|
||||
t[al + bl] = '\n';
|
||||
t[al + bl + 1] = 0;
|
||||
|
||||
scheme_console_output(t, al + bl + 1);
|
||||
}
|
||||
|
||||
static void
|
||||
call_error(char *buffer, int len, Scheme_Object *exn)
|
||||
{
|
||||
|
@ -763,9 +746,8 @@ call_error(char *buffer, int len, Scheme_Object *exn)
|
|||
scheme_pop_break_enable(&cframe2, 0);
|
||||
scheme_pop_continuation_frame(&cframe);
|
||||
|
||||
/* Uh-oh; record the error and fall back to the default escaper */
|
||||
scheme_inescapeable_error("error escape handler did not escape; calling the default error escape handler", "");
|
||||
scheme_longjmp(savebuf, 1); /* force an exit */
|
||||
/* Didn't escape, so fall back to the default escaper: */
|
||||
def_error_escape_proc(0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2418,9 +2400,9 @@ emergency_error_display_proc(int argc, Scheme_Object *argv[])
|
|||
|
||||
s = scheme_char_string_to_byte_string(argv[0]);
|
||||
|
||||
scheme_console_output(SCHEME_BYTE_STR_VAL(s),
|
||||
SCHEME_BYTE_STRTAG_VAL(s));
|
||||
scheme_console_output("\n", 1);
|
||||
scheme_log_message(NULL, SCHEME_LOG_ERROR,
|
||||
SCHEME_BYTE_STR_VAL(s), SCHEME_BYTE_STRTAG_VAL(s),
|
||||
scheme_false);
|
||||
|
||||
return scheme_void;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user