mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
feat: Add better error messages for unstable APIs (#25519)
This commit improves error messages for unstable APIs: - `--unstable-broadcast-channel` - `--unstable-cron` - `--unstable-http` - `--unstable-kv` - `--unstable-temporal` By providing information and hints what went wrong and how the error can be fixed. It reuses the same infra that was added in https://github.com/denoland/deno/pull/21764.
This commit is contained in:
parent
d9b5bccdea
commit
04a9cc95ac
17 changed files with 138 additions and 24 deletions
68
cli/main.rs
68
cli/main.rs
|
@ -337,17 +337,61 @@ fn exit_with_message(message: &str, code: i32) -> ! {
|
||||||
std::process::exit(code);
|
std::process::exit(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_suggestions_for_commonjs_error(e: &JsError) -> Vec<FixSuggestion> {
|
fn get_suggestions_for_terminal_errors(e: &JsError) -> Vec<FixSuggestion> {
|
||||||
if e.name.as_deref() == Some("ReferenceError") {
|
if let Some(msg) = &e.message {
|
||||||
if let Some(msg) = &e.message {
|
if msg.contains("module is not defined")
|
||||||
if msg.contains("module is not defined")
|
|| msg.contains("exports is not defined")
|
||||||
|| msg.contains("exports is not defined")
|
{
|
||||||
{
|
return vec![
|
||||||
return vec![
|
FixSuggestion::info(
|
||||||
FixSuggestion::info("Deno does not support CommonJS modules without `.cjs` extension."),
|
"Deno does not support CommonJS modules without `.cjs` extension.",
|
||||||
FixSuggestion::hint("Rewrite this module to ESM or change the file extension to `.cjs`."),
|
),
|
||||||
];
|
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("createHttpClient is not a function") {
|
||||||
|
return vec![
|
||||||
|
FixSuggestion::info("Deno.createHttpClient() is an unstable API."),
|
||||||
|
FixSuggestion::hint(
|
||||||
|
"Run again with `--unstable-http` 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.",
|
||||||
|
),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,7 +403,7 @@ fn exit_for_error(error: AnyError) -> ! {
|
||||||
let mut error_code = 1;
|
let mut error_code = 1;
|
||||||
|
|
||||||
if let Some(e) = error.downcast_ref::<JsError>() {
|
if let Some(e) = error.downcast_ref::<JsError>() {
|
||||||
let suggestions = get_suggestions_for_commonjs_error(e);
|
let suggestions = get_suggestions_for_terminal_errors(e);
|
||||||
error_string = format_js_error_with_suggestions(e, suggestions);
|
error_string = format_js_error_with_suggestions(e, suggestions);
|
||||||
} else if let Some(SnapshotFromLockfileError::IntegrityCheckFailed(e)) =
|
} else if let Some(SnapshotFromLockfileError::IntegrityCheckFailed(e)) =
|
||||||
error.downcast_ref::<SnapshotFromLockfileError>()
|
error.downcast_ref::<SnapshotFromLockfileError>()
|
||||||
|
|
|
@ -4811,13 +4811,6 @@ itest!(unstable_temporal_api_config_file {
|
||||||
exit_code: 0,
|
exit_code: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
itest!(unstable_temporal_api_missing_flag {
|
|
||||||
args: "run --no-config run/unstable_temporal_api/missing_flag.js",
|
|
||||||
output: "run/unstable_temporal_api/missing_flag.out",
|
|
||||||
http_server: false,
|
|
||||||
exit_code: 1,
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO(bartlomieju): temporary disabled
|
// TODO(bartlomieju): temporary disabled
|
||||||
// itest!(warn_on_deprecated_api {
|
// itest!(warn_on_deprecated_api {
|
||||||
// args: "run -A run/warn_on_deprecated_api/main.js",
|
// args: "run -A run/warn_on_deprecated_api/main.js",
|
||||||
|
|
34
tests/specs/run/unstable/__test__.jsonc
Normal file
34
tests/specs/run/unstable/__test__.jsonc
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
{
|
||||||
|
"tests": {
|
||||||
|
"broadcast_channel": {
|
||||||
|
"args": "run broadcast_channel.ts",
|
||||||
|
"exitCode": 1,
|
||||||
|
"output": "broadcast_channel.out"
|
||||||
|
},
|
||||||
|
"cron": {
|
||||||
|
"args": "run cron.ts",
|
||||||
|
"exitCode": 1,
|
||||||
|
"output": "cron.out"
|
||||||
|
},
|
||||||
|
"http": {
|
||||||
|
"args": "run http.ts",
|
||||||
|
"exitCode": 1,
|
||||||
|
"output": "http.out"
|
||||||
|
},
|
||||||
|
"http_wss": {
|
||||||
|
"args": "run http_wss.ts",
|
||||||
|
"exitCode": 1,
|
||||||
|
"output": "http_wss.out"
|
||||||
|
},
|
||||||
|
"kv": {
|
||||||
|
"args": "run kv.ts",
|
||||||
|
"exitCode": 1,
|
||||||
|
"output": "kv.out"
|
||||||
|
},
|
||||||
|
"temporal": {
|
||||||
|
"args": "run temporal.ts",
|
||||||
|
"exitCode": 1,
|
||||||
|
"output": "temporal.out"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
tests/specs/run/unstable/broadcast_channel.out
Normal file
7
tests/specs/run/unstable/broadcast_channel.out
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
error: Uncaught (in promise) ReferenceError: BroadcastChannel is not defined
|
||||||
|
new BroadcastChannel("hello");
|
||||||
|
^
|
||||||
|
at [WILDCARD]broadcast_channel.ts:1:1
|
||||||
|
|
||||||
|
info: BroadcastChannel is an unstable API.
|
||||||
|
hint: Run again with `--unstable-broadcast-channel` flag to enable this API.
|
1
tests/specs/run/unstable/broadcast_channel.ts
Normal file
1
tests/specs/run/unstable/broadcast_channel.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
new BroadcastChannel("hello");
|
7
tests/specs/run/unstable/cron.out
Normal file
7
tests/specs/run/unstable/cron.out
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
error: Uncaught (in promise) TypeError: Deno.cron is not a function
|
||||||
|
Deno.cron();
|
||||||
|
^
|
||||||
|
at [WILDCARD]cron.ts:1:6
|
||||||
|
|
||||||
|
info: Deno.cron() is an unstable API.
|
||||||
|
hint: Run again with `--unstable-cron` flag to enable this API.
|
1
tests/specs/run/unstable/cron.ts
Normal file
1
tests/specs/run/unstable/cron.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Deno.cron();
|
7
tests/specs/run/unstable/http.out
Normal file
7
tests/specs/run/unstable/http.out
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
error: Uncaught (in promise) TypeError: Deno.createHttpClient is not a function
|
||||||
|
Deno.createHttpClient();
|
||||||
|
^
|
||||||
|
at [WILDCARD]http.ts:1:6
|
||||||
|
|
||||||
|
info: Deno.createHttpClient() is an unstable API.
|
||||||
|
hint: Run again with `--unstable-http` flag to enable this API.
|
1
tests/specs/run/unstable/http.ts
Normal file
1
tests/specs/run/unstable/http.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Deno.createHttpClient();
|
7
tests/specs/run/unstable/http_wss.out
Normal file
7
tests/specs/run/unstable/http_wss.out
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
error: Uncaught (in promise) ReferenceError: WebSocketStream is not defined
|
||||||
|
const wss = new WebSocketStream("ws://127.0.0.1:4513");
|
||||||
|
^
|
||||||
|
at [WILDCARD]http_wss.ts:1:13
|
||||||
|
|
||||||
|
info: new WebSocketStream() is an unstable API.
|
||||||
|
hint: Run again with `--unstable-net` flag to enable this API.
|
1
tests/specs/run/unstable/http_wss.ts
Normal file
1
tests/specs/run/unstable/http_wss.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
const wss = new WebSocketStream("ws://127.0.0.1:4513");
|
7
tests/specs/run/unstable/kv.out
Normal file
7
tests/specs/run/unstable/kv.out
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
error: Uncaught (in promise) TypeError: Deno.openKv is not a function
|
||||||
|
const db = await Deno.openKv();
|
||||||
|
^
|
||||||
|
at [WILDCARD]kv.ts:1:23
|
||||||
|
|
||||||
|
info: Deno.openKv() is an unstable API.
|
||||||
|
hint: Run again with `--unstable-kv` flag to enable this API.
|
1
tests/specs/run/unstable/kv.ts
Normal file
1
tests/specs/run/unstable/kv.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
const db = await Deno.openKv();
|
7
tests/specs/run/unstable/temporal.out
Normal file
7
tests/specs/run/unstable/temporal.out
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
error: Uncaught (in promise) ReferenceError: Temporal is not defined
|
||||||
|
Temporal.Now.instant();
|
||||||
|
^
|
||||||
|
at [WILDCARD]temporal.ts:1:1
|
||||||
|
|
||||||
|
info: Temporal is an unstable API.
|
||||||
|
hint: Run again with `--unstable-temporal` flag to enable this API.
|
|
@ -1,4 +0,0 @@
|
||||||
error: Uncaught (in promise) ReferenceError: Temporal is not defined
|
|
||||||
Temporal.Now.instant();
|
|
||||||
^
|
|
||||||
at [WILDCARD]missing_flag.js:1:1
|
|
|
@ -220,7 +220,7 @@ async function ensureNoNewITests() {
|
||||||
"pm_tests.rs": 0,
|
"pm_tests.rs": 0,
|
||||||
"publish_tests.rs": 0,
|
"publish_tests.rs": 0,
|
||||||
"repl_tests.rs": 0,
|
"repl_tests.rs": 0,
|
||||||
"run_tests.rs": 348,
|
"run_tests.rs": 347,
|
||||||
"shared_library_tests.rs": 0,
|
"shared_library_tests.rs": 0,
|
||||||
"task_tests.rs": 30,
|
"task_tests.rs": 30,
|
||||||
"test_tests.rs": 74,
|
"test_tests.rs": 74,
|
||||||
|
|
Loading…
Reference in a new issue