summaryrefslogtreecommitdiff
path: root/core/error.rs
diff options
context:
space:
mode:
authorNayeem Rahman <nayeemrmn99@gmail.com>2022-06-06 19:26:57 +0100
committerGitHub <noreply@github.com>2022-06-06 20:26:57 +0200
commite3eae662f3d753141571bd132ccb199f95c745ea (patch)
treee0cdad78f409c9b221b909d0d7dfcee286e6325f /core/error.rs
parent1081659be176a59512a7e9e3dc93e13046a26aec (diff)
fix: Format non-error exceptions (#14604)
This commit adds "Deno.core.setFormatExceptionCallback" which can be used to provide custom formatting for errors. It is useful in cases when user throws something that is non-Error (eg. a string, plain object, etc).
Diffstat (limited to 'core/error.rs')
-rw-r--r--core/error.rs38
1 files changed, 28 insertions, 10 deletions
diff --git a/core/error.rs b/core/error.rs
index 2ba053802..c3bf6e861 100644
--- a/core/error.rs
+++ b/core/error.rs
@@ -191,6 +191,20 @@ impl JsError {
let msg = v8::Exception::create_message(scope, exception);
+ let mut exception_message = None;
+ let state_rc = JsRuntime::state(scope);
+ let state = state_rc.borrow();
+ if let Some(format_exception_cb) = &state.js_format_exception_cb {
+ let format_exception_cb = format_exception_cb.open(scope);
+ let this = v8::undefined(scope).into();
+ let formatted = format_exception_cb.call(scope, this, &[exception]);
+ if let Some(formatted) = formatted {
+ if formatted.is_string() {
+ exception_message = Some(formatted.to_rust_string_lossy(scope));
+ }
+ }
+ }
+
if is_instance_of_error(scope, exception) {
// The exception is a JS Error object.
let exception: v8::Local<v8::Object> = exception.try_into().unwrap();
@@ -200,15 +214,17 @@ impl JsError {
// Get the message by formatting error.name and error.message.
let name = e.name.clone().unwrap_or_else(|| "Error".to_string());
let message_prop = e.message.clone().unwrap_or_else(|| "".to_string());
- let exception_message = if !name.is_empty() && !message_prop.is_empty() {
- format!("Uncaught {}: {}", name, message_prop)
- } else if !name.is_empty() {
- format!("Uncaught {}", name)
- } else if !message_prop.is_empty() {
- format!("Uncaught {}", message_prop)
- } else {
- "Uncaught".to_string()
- };
+ let exception_message = exception_message.unwrap_or_else(|| {
+ if !name.is_empty() && !message_prop.is_empty() {
+ format!("Uncaught {}: {}", name, message_prop)
+ } else if !name.is_empty() {
+ format!("Uncaught {}", name)
+ } else if !message_prop.is_empty() {
+ format!("Uncaught {}", message_prop)
+ } else {
+ "Uncaught".to_string()
+ }
+ });
let cause = cause.and_then(|cause| {
if cause.is_undefined() || seen.contains(&cause) {
None
@@ -334,13 +350,15 @@ impl JsError {
aggregated,
}
} else {
+ let exception_message = exception_message
+ .unwrap_or_else(|| msg.get(scope).to_rust_string_lossy(scope));
// The exception is not a JS Error object.
// Get the message given by V8::Exception::create_message(), and provide
// empty frames.
Self {
name: None,
message: None,
- exception_message: msg.get(scope).to_rust_string_lossy(scope),
+ exception_message,
cause: None,
source_line: None,
source_line_frame_index: None,