From cb385d9e4acbd81235c3784d7e56b49c3fa41dd3 Mon Sep 17 00:00:00 2001 From: Leo Kettmeir Date: Mon, 14 Oct 2024 13:53:17 -0700 Subject: refactor(ext/webstorage): use concrete error types (#26173) --- runtime/errors.rs | 15 ++++++++++++++- runtime/ops/worker_host.rs | 11 +++++------ 2 files changed, 19 insertions(+), 7 deletions(-) (limited to 'runtime') diff --git a/runtime/errors.rs b/runtime/errors.rs index 4c6aeab98..bc28339ad 100644 --- a/runtime/errors.rs +++ b/runtime/errors.rs @@ -18,6 +18,7 @@ use deno_core::url; use deno_core::ModuleResolutionError; use deno_cron::CronError; use deno_tls::TlsError; +use deno_webstorage::WebStorageError; use std::env; use std::error::Error; use std::io; @@ -158,6 +159,15 @@ pub fn get_nix_error_class(error: &nix::Error) -> &'static str { } } +fn get_webstorage_class_name(e: &WebStorageError) -> &'static str { + match e { + WebStorageError::ContextNotSupported => "DOMExceptionNotSupportedError", + WebStorageError::Sqlite(_) => todo!(), + WebStorageError::Io(e) => get_io_error_class(e), + WebStorageError::StorageExceeded => "DOMExceptionQuotaExceededError", + } +} + fn get_tls_error_class(e: &TlsError) -> &'static str { match e { TlsError::Rustls(_) => "Error", @@ -221,7 +231,6 @@ pub fn get_error_class_name(e: &AnyError) -> Option<&'static str> { deno_core::error::get_custom_error_class(e) .or_else(|| deno_webgpu::error::get_error_class_name(e)) .or_else(|| deno_web::get_error_class_name(e)) - .or_else(|| deno_webstorage::get_not_supported_error_class_name(e)) .or_else(|| deno_websocket::get_network_error_class_name(e)) .or_else(|| e.downcast_ref::().map(get_tls_error_class)) .or_else(|| e.downcast_ref::().map(get_cron_error_class)) @@ -231,6 +240,10 @@ pub fn get_error_class_name(e: &AnyError) -> Option<&'static str> { e.downcast_ref::() .map(get_broadcast_channel_error) }) + .or_else(|| { + e.downcast_ref::() + .map(get_webstorage_class_name) + }) .or_else(|| { e.downcast_ref::() .map(get_dlopen_error_class) diff --git a/runtime/ops/worker_host.rs b/runtime/ops/worker_host.rs index b9fd06654..61e5ef3e0 100644 --- a/runtime/ops/worker_host.rs +++ b/runtime/ops/worker_host.rs @@ -10,6 +10,7 @@ use crate::web_worker::WorkerControlEvent; use crate::web_worker::WorkerId; use crate::web_worker::WorkerMetadata; use crate::worker::FormatJsErrorFn; +use deno_core::error::custom_error; use deno_core::error::AnyError; use deno_core::op2; use deno_core::serde::Deserialize; @@ -136,12 +137,10 @@ fn op_create_worker( let worker_type = args.worker_type; if let WebWorkerType::Classic = worker_type { if let TestingFeaturesEnabled(false) = state.borrow() { - return Err( - deno_webstorage::DomExceptionNotSupportedError::new( - "Classic workers are not supported.", - ) - .into(), - ); + return Err(custom_error( + "DOMExceptionNotSupportedError", + "Classic workers are not supported.", + )); } } -- cgit v1.2.3 From 48cbf85add1a9a5c3e583c68c80d16420e606502 Mon Sep 17 00:00:00 2001 From: Leo Kettmeir Date: Mon, 14 Oct 2024 14:15:31 -0700 Subject: refactor(ext/url): use concrete error types (#26172) --- runtime/errors.rs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'runtime') diff --git a/runtime/errors.rs b/runtime/errors.rs index bc28339ad..573563595 100644 --- a/runtime/errors.rs +++ b/runtime/errors.rs @@ -244,6 +244,10 @@ pub fn get_error_class_name(e: &AnyError) -> Option<&'static str> { e.downcast_ref::() .map(get_webstorage_class_name) }) + .or_else(|| { + e.downcast_ref::() + .map(|_| "TypeError") + }) .or_else(|| { e.downcast_ref::() .map(get_dlopen_error_class) -- cgit v1.2.3 From ee7d4501435f0ebd655c8b50bd6e41ca19e71abc Mon Sep 17 00:00:00 2001 From: Leo Kettmeir Date: Mon, 14 Oct 2024 15:05:49 -0700 Subject: refactor(ext/ffi): use concrete error types (#26170) --- runtime/errors.rs | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) (limited to 'runtime') diff --git a/runtime/errors.rs b/runtime/errors.rs index 573563595..612a66b6e 100644 --- a/runtime/errors.rs +++ b/runtime/errors.rs @@ -17,6 +17,12 @@ use deno_core::serde_json; use deno_core::url; use deno_core::ModuleResolutionError; use deno_cron::CronError; +use deno_ffi::CallError; +use deno_ffi::CallbackError; +use deno_ffi::DlfcnError; +use deno_ffi::IRError; +use deno_ffi::ReprError; +use deno_ffi::StaticError; use deno_tls::TlsError; use deno_webstorage::WebStorageError; use std::env; @@ -159,6 +165,65 @@ pub fn get_nix_error_class(error: &nix::Error) -> &'static str { } } +fn get_ffi_repr_error_class(e: &ReprError) -> &'static str { + match e { + ReprError::InvalidOffset => "TypeError", + ReprError::InvalidArrayBuffer => "TypeError", + ReprError::DestinationLengthTooShort => "RangeError", + ReprError::InvalidCString => "TypeError", + ReprError::CStringTooLong => "TypeError", + ReprError::InvalidBool => "TypeError", + ReprError::InvalidU8 => "TypeError", + ReprError::InvalidI8 => "TypeError", + ReprError::InvalidU16 => "TypeError", + ReprError::InvalidI16 => "TypeError", + ReprError::InvalidU32 => "TypeError", + ReprError::InvalidI32 => "TypeError", + ReprError::InvalidU64 => "TypeError", + ReprError::InvalidI64 => "TypeError", + ReprError::InvalidF32 => "TypeError", + ReprError::InvalidF64 => "TypeError", + ReprError::InvalidPointer => "TypeError", + ReprError::Permission(e) => get_error_class_name(e).unwrap_or("Error"), + } +} + +fn get_ffi_dlfcn_error_class(e: &DlfcnError) -> &'static str { + match e { + DlfcnError::RegisterSymbol { .. } => "Error", + DlfcnError::Dlopen(_) => "Error", + DlfcnError::Permission(e) => get_error_class_name(e).unwrap_or("Error"), + DlfcnError::Other(e) => get_error_class_name(e).unwrap_or("Error"), + } +} + +fn get_ffi_static_error_class(e: &StaticError) -> &'static str { + match e { + StaticError::Dlfcn(e) => get_ffi_dlfcn_error_class(e), + StaticError::InvalidTypeVoid => "TypeError", + StaticError::InvalidTypeStruct => "TypeError", + StaticError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), + } +} + +fn get_ffi_callback_error_class(e: &CallbackError) -> &'static str { + match e { + CallbackError::Resource(e) => get_error_class_name(e).unwrap_or("Error"), + CallbackError::Other(e) => get_error_class_name(e).unwrap_or("Error"), + CallbackError::Permission(e) => get_error_class_name(e).unwrap_or("Error"), + } +} + +fn get_ffi_call_error_class(e: &CallError) -> &'static str { + match e { + CallError::IR(_) => "TypeError", + CallError::NonblockingCallFailure(_) => "Error", + CallError::InvalidSymbol(_) => "TypeError", + CallError::Permission(e) => get_error_class_name(e).unwrap_or("Error"), + CallError::Callback(e) => get_ffi_callback_error_class(e), + } +} + fn get_webstorage_class_name(e: &WebStorageError) -> &'static str { match e { WebStorageError::ContextNotSupported => "DOMExceptionNotSupportedError", @@ -232,6 +297,21 @@ pub fn get_error_class_name(e: &AnyError) -> Option<&'static str> { .or_else(|| deno_webgpu::error::get_error_class_name(e)) .or_else(|| deno_web::get_error_class_name(e)) .or_else(|| deno_websocket::get_network_error_class_name(e)) + .or_else(|| e.downcast_ref::().map(|_| "TypeError")) + .or_else(|| e.downcast_ref::().map(get_ffi_repr_error_class)) + .or_else(|| { + e.downcast_ref::() + .map(get_ffi_dlfcn_error_class) + }) + .or_else(|| { + e.downcast_ref::() + .map(get_ffi_static_error_class) + }) + .or_else(|| { + e.downcast_ref::() + .map(get_ffi_callback_error_class) + }) + .or_else(|| e.downcast_ref::().map(get_ffi_call_error_class)) .or_else(|| e.downcast_ref::().map(get_tls_error_class)) .or_else(|| e.downcast_ref::().map(get_cron_error_class)) .or_else(|| e.downcast_ref::().map(get_canvas_error)) -- cgit v1.2.3 From 533a9b108677f1560fe55882771a0be2bb0b0fd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E7=82=B3=E6=9D=83?= <695601626@qq.com> Date: Wed, 16 Oct 2024 00:10:07 +0800 Subject: chore: upgrade to rust 1.81.0 (#26261) --- runtime/permissions/prompter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime') diff --git a/runtime/permissions/prompter.rs b/runtime/permissions/prompter.rs index e48e0af10..3d7536928 100644 --- a/runtime/permissions/prompter.rs +++ b/runtime/permissions/prompter.rs @@ -366,7 +366,7 @@ impl PermissionPrompter for TtyPrompter { let mut input = String::new(); let result = stdin_lock.read_line(&mut input); - let input = input.trim_end_matches(|c| c == '\r' || c == '\n'); + let input = input.trim_end_matches(['\r', '\n']); if result.is_err() || input.len() != 1 { break PromptResponse::Deny; }; -- cgit v1.2.3 From 38888061698f230f2288cf520daf86d781c395bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Tue, 15 Oct 2024 17:59:28 +0100 Subject: refactor: always apply hint when formatting JsError (#26252) Moves code for generating suggestions and hint to `cli/fmt_errors.rs`. This effectively applies suggestion to any place that format JS errors in terminal, like `deno test`. Addresses https://github.com/denoland/deno/pull/26218#issuecomment-2409139055 --- runtime/fmt_errors.rs | 105 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 91 insertions(+), 14 deletions(-) (limited to 'runtime') diff --git a/runtime/fmt_errors.rs b/runtime/fmt_errors.rs index 44a947732..0d4274e8a 100644 --- a/runtime/fmt_errors.rs +++ b/runtime/fmt_errors.rs @@ -282,28 +282,105 @@ fn format_js_error_inner( s } -/// Format a [`JsError`] for terminal output. -pub fn format_js_error(js_error: &JsError) -> String { - let circular = - find_recursive_cause(js_error).map(|reference| IndexedErrorReference { - reference, - index: 1, - }); +fn get_suggestions_for_terminal_errors(e: &JsError) -> Vec { + if let Some(msg) = &e.message { + if msg.contains("module is not defined") + || msg.contains("exports is not defined") + { + return vec![ + FixSuggestion::info( + "Deno does not support CommonJS modules without `.cjs` extension.", + ), + FixSuggestion::hint( + "Rewrite this module to ESM or change the file extension to `.cjs`.", + ), + ]; + } else if msg.contains("openKv is not a function") { + return vec![ + FixSuggestion::info("Deno.openKv() is an unstable API."), + FixSuggestion::hint( + "Run again with `--unstable-kv` flag to enable this API.", + ), + ]; + } else if msg.contains("cron is not a function") { + return vec![ + FixSuggestion::info("Deno.cron() is an unstable API."), + FixSuggestion::hint( + "Run again with `--unstable-cron` flag to enable this API.", + ), + ]; + } else if msg.contains("WebSocketStream is not defined") { + return vec![ + FixSuggestion::info("new WebSocketStream() is an unstable API."), + FixSuggestion::hint( + "Run again with `--unstable-net` flag to enable this API.", + ), + ]; + } else if msg.contains("Temporal is not defined") { + return vec![ + FixSuggestion::info("Temporal is an unstable API."), + FixSuggestion::hint( + "Run again with `--unstable-temporal` flag to enable this API.", + ), + ]; + } else if msg.contains("BroadcastChannel is not defined") { + return vec![ + FixSuggestion::info("BroadcastChannel is an unstable API."), + FixSuggestion::hint( + "Run again with `--unstable-broadcast-channel` flag to enable this API.", + ), + ]; + } else if msg.contains("window is not defined") { + return vec![ + FixSuggestion::info("window global is not available in Deno 2."), + FixSuggestion::hint("Replace `window` with `globalThis`."), + ]; + } else if msg.contains("UnsafeWindowSurface is not a constructor") { + return vec![ + FixSuggestion::info("Deno.UnsafeWindowSurface is an unstable API."), + FixSuggestion::hint( + "Run again with `--unstable-webgpu` flag to enable this API.", + ), + ]; + // Try to capture errors like: + // ``` + // Uncaught Error: Cannot find module '../build/Release/canvas.node' + // Require stack: + // - /.../deno/npm/registry.npmjs.org/canvas/2.11.2/lib/bindings.js + // - /.../.cache/deno/npm/registry.npmjs.org/canvas/2.11.2/lib/canvas.js + // ``` + } else if msg.contains("Cannot find module") + && msg.contains("Require stack") + && msg.contains(".node'") + { + return vec![ + FixSuggestion::info_multiline( + &[ + "Trying to execute an npm package using Node-API addons,", + "these packages require local `node_modules` directory to be present." + ] + ), + FixSuggestion::hint_multiline( + &[ + "Add `\"nodeModulesDir\": \"auto\" option to `deno.json`, and then run", + "`deno install --allow-scripts=npm: --entrypoint