diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2024-09-05 13:49:07 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-05 12:49:07 +0000 |
commit | 794d347ec68fa969ffed231d0844a59a215d2344 (patch) | |
tree | 237b26bba35eb570683de86f68e0bff9bde162dd /runtime/fmt_errors.rs | |
parent | dda63287456aae5cd4f7f428e23b52cb8c0005e5 (diff) |
fix: add suggestion how to fix importing CJS module (#21764)
```
$ cat exports_error.js
Object.defineProperty(exports, "__esModule", { value: true });
$ deno exports_error.js
error: Uncaught (in promise) ReferenceError: exports is not defined
Object.defineProperty(exports, "__esModule", { value: true });
^
at file:///exports_error.js:1:23
info: Deno doesn't support CommonJS modules without `.cjs` extension.
hint: Rewrite this module to ESM or change the file extension to `.cjs`.
```
Diffstat (limited to 'runtime/fmt_errors.rs')
-rw-r--r-- | runtime/fmt_errors.rs | 63 |
1 files changed, 61 insertions, 2 deletions
diff --git a/runtime/fmt_errors.rs b/runtime/fmt_errors.rs index 4687dbd47..b2cec2a5a 100644 --- a/runtime/fmt_errors.rs +++ b/runtime/fmt_errors.rs @@ -20,6 +20,34 @@ struct IndexedErrorReference<'a> { index: usize, } +#[derive(Debug)] +enum FixSuggestionKind { + Info, + Hint, +} + +#[derive(Debug)] +pub struct FixSuggestion<'a> { + kind: FixSuggestionKind, + message: &'a str, +} + +impl<'a> FixSuggestion<'a> { + pub fn info(message: &'a str) -> Self { + Self { + kind: FixSuggestionKind::Info, + message, + } + } + + pub fn hint(message: &'a str) -> Self { + Self { + kind: FixSuggestionKind::Hint, + message, + } + } +} + struct AnsiColors; impl deno_core::error::ErrorFormat for AnsiColors { @@ -129,6 +157,7 @@ fn format_aggregated_error( index: nested_circular_reference_index, }), false, + vec![], ); for line in error_string.trim_start_matches("Uncaught ").lines() { @@ -143,6 +172,7 @@ fn format_js_error_inner( js_error: &JsError, circular: Option<IndexedErrorReference>, include_source_code: bool, + suggestions: Vec<FixSuggestion>, ) -> String { let mut s = String::new(); @@ -190,7 +220,7 @@ fn format_js_error_inner( let error_string = if is_caused_by_circular { cyan(format!("[Circular *{}]", circular.unwrap().index)).to_string() } else { - format_js_error_inner(cause, circular, false) + format_js_error_inner(cause, circular, false, vec![]) }; write!( @@ -200,6 +230,21 @@ fn format_js_error_inner( ) .unwrap(); } + if !suggestions.is_empty() { + write!(s, "\n\n").unwrap(); + for (index, suggestion) in suggestions.iter().enumerate() { + write!(s, " ").unwrap(); + match suggestion.kind { + FixSuggestionKind::Hint => write!(s, "{} ", cyan("hint:")).unwrap(), + FixSuggestionKind::Info => write!(s, "{} ", yellow("info:")).unwrap(), + }; + write!(s, "{}", suggestion.message).unwrap(); + if index != (suggestions.len() - 1) { + writeln!(s).unwrap(); + } + } + } + s } @@ -211,7 +256,21 @@ pub fn format_js_error(js_error: &JsError) -> String { index: 1, }); - format_js_error_inner(js_error, circular, true) + format_js_error_inner(js_error, circular, true, vec![]) +} + +/// Format a [`JsError`] for terminal output, printing additional suggestions. +pub fn format_js_error_with_suggestions( + js_error: &JsError, + suggestions: Vec<FixSuggestion>, +) -> String { + let circular = + find_recursive_cause(js_error).map(|reference| IndexedErrorReference { + reference, + index: 1, + }); + + format_js_error_inner(js_error, circular, true, suggestions) } #[cfg(test)] |