1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-25 15:29:32 -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:
Bartek Iwańczuk 2024-09-09 21:51:55 +01:00 committed by GitHub
parent d9b5bccdea
commit 04a9cc95ac
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 138 additions and 24 deletions

View file

@ -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("Deno does not support CommonJS modules without `.cjs` extension."), FixSuggestion::info(
FixSuggestion::hint("Rewrite this module to ESM or change the file extension to `.cjs`."), "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("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>()

View file

@ -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",

View 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"
}
}
}

View 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.

View file

@ -0,0 +1 @@
new BroadcastChannel("hello");

View 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.

View file

@ -0,0 +1 @@
Deno.cron();

View 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.

View file

@ -0,0 +1 @@
Deno.createHttpClient();

View 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.

View file

@ -0,0 +1 @@
const wss = new WebSocketStream("ws://127.0.0.1:4513");

View 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.

View file

@ -0,0 +1 @@
const db = await Deno.openKv();

View 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.

View file

@ -1,4 +0,0 @@
error: Uncaught (in promise) ReferenceError: Temporal is not defined
Temporal.Now.instant();
^
at [WILDCARD]missing_flag.js:1:1

View file

@ -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,