mirror of
https://github.com/denoland/deno.git
synced 2025-01-20 20:42:19 -05:00
refactor: update deno_core for error refactor (#26867)
Closes #26171 --------- Co-authored-by: David Sherret <dsherret@gmail.com>
This commit is contained in:
parent
814da49dff
commit
ea30e188a8
214 changed files with 3787 additions and 4210 deletions
157
Cargo.lock
generated
157
Cargo.lock
generated
|
@ -1275,7 +1275,7 @@ dependencies = [
|
|||
"deno_npm",
|
||||
"deno_npm_cache",
|
||||
"deno_package_json",
|
||||
"deno_path_util 0.3.0",
|
||||
"deno_path_util",
|
||||
"deno_resolver",
|
||||
"deno_runtime",
|
||||
"deno_semver",
|
||||
|
@ -1434,6 +1434,7 @@ version = "0.178.0"
|
|||
dependencies = [
|
||||
"async-trait",
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
"thiserror 2.0.3",
|
||||
"tokio",
|
||||
"uuid",
|
||||
|
@ -1445,6 +1446,7 @@ version = "0.116.0"
|
|||
dependencies = [
|
||||
"async-trait",
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
"rusqlite",
|
||||
"serde",
|
||||
"sha2",
|
||||
|
@ -1467,7 +1469,7 @@ dependencies = [
|
|||
"data-url",
|
||||
"deno_error",
|
||||
"deno_media_type",
|
||||
"deno_path_util 0.3.0",
|
||||
"deno_path_util",
|
||||
"http 1.1.0",
|
||||
"indexmap 2.3.0",
|
||||
"log",
|
||||
|
@ -1486,6 +1488,7 @@ name = "deno_canvas"
|
|||
version = "0.53.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
"deno_webgpu",
|
||||
"image",
|
||||
"serde",
|
||||
|
@ -1494,13 +1497,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_config"
|
||||
version = "0.42.0"
|
||||
version = "0.43.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b45aaf31e58ca915d5c0746bf8e2d07b94635154ad9e5afe5ff265cae6187b19"
|
||||
checksum = "6c4c11bd51ef6738cabfc3c53f16c209a0b8615cb1e4e5bf3b14e3b5deebfe21"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"boxed_error",
|
||||
"deno_error",
|
||||
"deno_package_json",
|
||||
"deno_path_util 0.3.0",
|
||||
"deno_path_util",
|
||||
"deno_semver",
|
||||
"glob",
|
||||
"ignore",
|
||||
|
@ -1513,7 +1517,7 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"sys_traits",
|
||||
"thiserror 1.0.64",
|
||||
"thiserror 2.0.3",
|
||||
"url",
|
||||
]
|
||||
|
||||
|
@ -1526,9 +1530,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_core"
|
||||
version = "0.327.0"
|
||||
version = "0.330.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eaf8dff204b9c2415deb47b9f30d4d38b0925d0d88f1f9074e8e76f59e6d7ded"
|
||||
checksum = "fd38bbbd68ed873165ccb630322704b44140d3a8c8d50f898beac4d1a8a3358c"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"az",
|
||||
|
@ -1539,6 +1543,7 @@ dependencies = [
|
|||
"capacity_builder 0.1.3",
|
||||
"cooked-waker",
|
||||
"deno_core_icudata",
|
||||
"deno_error",
|
||||
"deno_ops",
|
||||
"deno_unsync",
|
||||
"futures",
|
||||
|
@ -1554,6 +1559,7 @@ dependencies = [
|
|||
"smallvec",
|
||||
"sourcemap 8.0.1",
|
||||
"static_assertions",
|
||||
"thiserror 2.0.3",
|
||||
"tokio",
|
||||
"url",
|
||||
"v8",
|
||||
|
@ -1574,6 +1580,7 @@ dependencies = [
|
|||
"async-trait",
|
||||
"chrono",
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
"saffron",
|
||||
"thiserror 2.0.3",
|
||||
"tokio",
|
||||
|
@ -1592,6 +1599,7 @@ dependencies = [
|
|||
"ctr",
|
||||
"curve25519-dalek",
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
"deno_web",
|
||||
"ed448-goldilocks",
|
||||
"elliptic-curve",
|
||||
|
@ -1618,16 +1626,17 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_doc"
|
||||
version = "0.161.3"
|
||||
version = "0.164.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "353a39c70d248af04600928cefc8066a9e4535fb6e7d7c518411e5efc822819f"
|
||||
checksum = "ad1edb02603c7e8a4003c84af2482a05e5eda3a14f1af275434fda89223f054d"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cfg-if",
|
||||
"comrak",
|
||||
"deno_ast",
|
||||
"deno_graph",
|
||||
"deno_path_util 0.2.2",
|
||||
"deno_path_util",
|
||||
"deno_terminal 0.2.0",
|
||||
"handlebars",
|
||||
"html-escape",
|
||||
"import_map",
|
||||
|
@ -1647,22 +1656,23 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_error"
|
||||
version = "0.5.2"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "199c66ffd17ee1a948904d33f3d3f364573951c1f9fb3f859bfe7770bf33862a"
|
||||
checksum = "c4da6a58de6932a96f84e133c072fd3b525966ee122a71f3efd48bbff2eed5ac"
|
||||
dependencies = [
|
||||
"deno_error_macro",
|
||||
"libc",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deno_error_macro"
|
||||
version = "0.5.2"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3cd99df6ae75443907e1f959fc42ec6dcea67a7bd083e76cf23a117102c9a2ce"
|
||||
checksum = "46351dff93aed2039407c91e2ded2a5591e42d2795ab3d111288625bb710d3d2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1677,7 +1687,8 @@ dependencies = [
|
|||
"bytes",
|
||||
"data-url",
|
||||
"deno_core",
|
||||
"deno_path_util 0.3.0",
|
||||
"deno_error",
|
||||
"deno_path_util",
|
||||
"deno_permissions",
|
||||
"deno_tls",
|
||||
"dyn-clone",
|
||||
|
@ -1710,6 +1721,7 @@ name = "deno_ffi"
|
|||
version = "0.171.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
"deno_permissions",
|
||||
"dlopen2",
|
||||
"dynasmrt",
|
||||
|
@ -1733,8 +1745,9 @@ dependencies = [
|
|||
"base32",
|
||||
"boxed_error",
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
"deno_io",
|
||||
"deno_path_util 0.3.0",
|
||||
"deno_path_util",
|
||||
"deno_permissions",
|
||||
"filetime",
|
||||
"junction",
|
||||
|
@ -1750,17 +1763,17 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_graph"
|
||||
version = "0.86.9"
|
||||
version = "0.87.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa96b7d353c0d36b108ec504272b148792f48dccaf29f302b39c46b43457bb94"
|
||||
checksum = "f56d4eb4b7c81ae920b6d18c45a1866924f93110caee80bbbc362dc28143f2bb"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"capacity_builder 0.5.0",
|
||||
"data-url",
|
||||
"deno_ast",
|
||||
"deno_error",
|
||||
"deno_media_type",
|
||||
"deno_path_util 0.3.0",
|
||||
"deno_path_util",
|
||||
"deno_semver",
|
||||
"deno_unsync",
|
||||
"encoding_rs",
|
||||
|
@ -1794,6 +1807,7 @@ dependencies = [
|
|||
"bytes",
|
||||
"cache_control",
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
"deno_net",
|
||||
"deno_websocket",
|
||||
"flate2",
|
||||
|
@ -1827,6 +1841,7 @@ version = "0.94.0"
|
|||
dependencies = [
|
||||
"async-trait",
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
"filetime",
|
||||
"fs3",
|
||||
"libc",
|
||||
|
@ -1853,8 +1868,9 @@ dependencies = [
|
|||
"bytes",
|
||||
"chrono",
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
"deno_fetch",
|
||||
"deno_path_util 0.3.0",
|
||||
"deno_path_util",
|
||||
"deno_permissions",
|
||||
"deno_tls",
|
||||
"denokv_proto",
|
||||
|
@ -1920,6 +1936,7 @@ name = "deno_napi"
|
|||
version = "0.115.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
"deno_permissions",
|
||||
"libc",
|
||||
"libloading 0.7.4",
|
||||
|
@ -1948,6 +1965,7 @@ name = "deno_net"
|
|||
version = "0.176.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
"deno_permissions",
|
||||
"deno_tls",
|
||||
"hickory-proto",
|
||||
|
@ -1977,13 +1995,14 @@ dependencies = [
|
|||
"const-oid",
|
||||
"data-encoding",
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
"deno_fetch",
|
||||
"deno_fs",
|
||||
"deno_io",
|
||||
"deno_media_type",
|
||||
"deno_net",
|
||||
"deno_package_json",
|
||||
"deno_path_util 0.3.0",
|
||||
"deno_path_util",
|
||||
"deno_permissions",
|
||||
"deno_whoami",
|
||||
"der",
|
||||
|
@ -2085,7 +2104,7 @@ dependencies = [
|
|||
"deno_core",
|
||||
"deno_error",
|
||||
"deno_npm",
|
||||
"deno_path_util 0.3.0",
|
||||
"deno_path_util",
|
||||
"deno_semver",
|
||||
"deno_unsync",
|
||||
"faster-hex",
|
||||
|
@ -2107,10 +2126,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deno_ops"
|
||||
version = "0.203.0"
|
||||
version = "0.206.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b146ca74cac431843486ade58e2accc16c11315fb2c6934590a52a73c56b7ec3"
|
||||
checksum = "4c25ffa9d088ea00748dbef870bba110ac22ebf8cf7b2e9eb288409c5d852af3"
|
||||
dependencies = [
|
||||
"indexmap 2.3.0",
|
||||
"proc-macro-rules",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -2118,7 +2138,7 @@ dependencies = [
|
|||
"strum",
|
||||
"strum_macros",
|
||||
"syn 2.0.87",
|
||||
"thiserror 1.0.64",
|
||||
"thiserror 2.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2129,7 +2149,7 @@ checksum = "e1d3c0f699ba2040669204ce24ab73720499fc290af843e4ce0fc8a9b3d67735"
|
|||
dependencies = [
|
||||
"boxed_error",
|
||||
"deno_error",
|
||||
"deno_path_util 0.3.0",
|
||||
"deno_path_util",
|
||||
"deno_semver",
|
||||
"indexmap 2.3.0",
|
||||
"serde",
|
||||
|
@ -2139,18 +2159,6 @@ dependencies = [
|
|||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deno_path_util"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b02c7d341e1b2cf089daff0f4fb2b4be8f3b5511b1d96040b3f7ed63a66c737b"
|
||||
dependencies = [
|
||||
"deno_error",
|
||||
"percent-encoding",
|
||||
"thiserror 2.0.3",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deno_path_util"
|
||||
version = "0.3.0"
|
||||
|
@ -2170,7 +2178,8 @@ version = "0.43.0"
|
|||
dependencies = [
|
||||
"capacity_builder 0.5.0",
|
||||
"deno_core",
|
||||
"deno_path_util 0.3.0",
|
||||
"deno_error",
|
||||
"deno_path_util",
|
||||
"deno_terminal 0.2.0",
|
||||
"fqdn",
|
||||
"libc",
|
||||
|
@ -2192,9 +2201,10 @@ dependencies = [
|
|||
"boxed_error",
|
||||
"dashmap",
|
||||
"deno_config",
|
||||
"deno_error",
|
||||
"deno_media_type",
|
||||
"deno_package_json",
|
||||
"deno_path_util 0.3.0",
|
||||
"deno_path_util",
|
||||
"deno_semver",
|
||||
"node_resolver",
|
||||
"sys_traits",
|
||||
|
@ -2216,6 +2226,7 @@ dependencies = [
|
|||
"deno_core",
|
||||
"deno_cron",
|
||||
"deno_crypto",
|
||||
"deno_error",
|
||||
"deno_fetch",
|
||||
"deno_ffi",
|
||||
"deno_fs",
|
||||
|
@ -2225,7 +2236,7 @@ dependencies = [
|
|||
"deno_napi",
|
||||
"deno_net",
|
||||
"deno_node",
|
||||
"deno_path_util 0.3.0",
|
||||
"deno_path_util",
|
||||
"deno_permissions",
|
||||
"deno_telemetry",
|
||||
"deno_terminal 0.2.0",
|
||||
|
@ -2314,6 +2325,7 @@ version = "0.6.0"
|
|||
dependencies = [
|
||||
"async-trait",
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
"http-body-util",
|
||||
"hyper 1.4.1",
|
||||
"hyper-util",
|
||||
|
@ -2326,6 +2338,7 @@ dependencies = [
|
|||
"opentelemetry_sdk",
|
||||
"pin-project",
|
||||
"serde",
|
||||
"thiserror 2.0.3",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
|
@ -2354,6 +2367,7 @@ name = "deno_tls"
|
|||
version = "0.171.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
"deno_native_certs",
|
||||
"rustls",
|
||||
"rustls-pemfile",
|
||||
|
@ -2406,6 +2420,7 @@ dependencies = [
|
|||
"deno_bench_util",
|
||||
"deno_console",
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
"deno_webidl",
|
||||
"thiserror 2.0.3",
|
||||
"urlpattern",
|
||||
|
@ -2421,6 +2436,7 @@ dependencies = [
|
|||
"deno_bench_util",
|
||||
"deno_console",
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
"deno_permissions",
|
||||
"deno_url",
|
||||
"deno_webidl",
|
||||
|
@ -2438,6 +2454,7 @@ name = "deno_webgpu"
|
|||
version = "0.151.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
"raw-window-handle",
|
||||
"serde",
|
||||
"thiserror 2.0.3",
|
||||
|
@ -2460,6 +2477,7 @@ version = "0.189.0"
|
|||
dependencies = [
|
||||
"bytes",
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
"deno_net",
|
||||
"deno_permissions",
|
||||
"deno_tls",
|
||||
|
@ -2481,6 +2499,7 @@ name = "deno_webstorage"
|
|||
version = "0.179.0"
|
||||
dependencies = [
|
||||
"deno_core",
|
||||
"deno_error",
|
||||
"deno_web",
|
||||
"rusqlite",
|
||||
"thiserror 2.0.3",
|
||||
|
@ -2498,13 +2517,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "denokv_proto"
|
||||
version = "0.8.4"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7ba1f99ed11a9c11e868a8521b1f71a7e1aba785d7f42ea9ecbdc01146c89ec"
|
||||
checksum = "d5b77de4d3b9215e14624d4f4eb16cb38c0810e3f5860ba3b3fc47d0537f9a4d"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"chrono",
|
||||
"deno_error",
|
||||
"futures",
|
||||
"num-bigint",
|
||||
"prost",
|
||||
|
@ -2514,15 +2533,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "denokv_remote"
|
||||
version = "0.8.4"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08ed833073189e8f6d03155fe3b05a024e75e29d8a28a4c2e9ec3b5c925e727b"
|
||||
checksum = "c6497c28eec268ed99f1e8664f0842935f02d1508529c67d94c57ca5d893d743"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-stream",
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"deno_error",
|
||||
"denokv_proto",
|
||||
"futures",
|
||||
"http 1.1.0",
|
||||
|
@ -2531,6 +2550,7 @@ dependencies = [
|
|||
"rand",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 2.0.3",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"url",
|
||||
|
@ -2539,14 +2559,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "denokv_sqlite"
|
||||
version = "0.8.4"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b790f01d1302d53a0c3cbd27de88a06b3abd64ec8ab8673924e490541c7c713"
|
||||
checksum = "dc0f21a450a35eb85760761401fddf9bfff9840127be07a6ca5c31863127913d"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-stream",
|
||||
"async-trait",
|
||||
"chrono",
|
||||
"deno_error",
|
||||
"denokv_proto",
|
||||
"futures",
|
||||
"hex",
|
||||
|
@ -2555,7 +2575,7 @@ dependencies = [
|
|||
"rand",
|
||||
"rusqlite",
|
||||
"serde_json",
|
||||
"thiserror 1.0.64",
|
||||
"thiserror 2.0.3",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"uuid",
|
||||
|
@ -4331,16 +4351,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "import_map"
|
||||
version = "0.20.1"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "351a787decc56f38d65d16d32687265045d6d6a4531b4a0e1b649def3590354e"
|
||||
checksum = "1215d4d92511fbbdaea50e750e91f2429598ef817f02b579158e92803b52c00a"
|
||||
dependencies = [
|
||||
"boxed_error",
|
||||
"deno_error",
|
||||
"indexmap 2.3.0",
|
||||
"log",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 1.0.64",
|
||||
"thiserror 2.0.3",
|
||||
"url",
|
||||
]
|
||||
|
||||
|
@ -5106,9 +5128,10 @@ dependencies = [
|
|||
"anyhow",
|
||||
"async-trait",
|
||||
"boxed_error",
|
||||
"deno_error",
|
||||
"deno_media_type",
|
||||
"deno_package_json",
|
||||
"deno_path_util 0.3.0",
|
||||
"deno_path_util",
|
||||
"futures",
|
||||
"lazy-regex",
|
||||
"once_cell",
|
||||
|
@ -6846,14 +6869,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_v8"
|
||||
version = "0.236.0"
|
||||
version = "0.239.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e23b3abce64010612f88f4ff689a959736f99eb3dc0dbf1c7903434b8bd8cda5"
|
||||
checksum = "3caa6d882827148e5d9052d9d8d6d1c9d6ad426ed00cab46cafb8c07a0e7126a"
|
||||
dependencies = [
|
||||
"deno_error",
|
||||
"num-bigint",
|
||||
"serde",
|
||||
"smallvec",
|
||||
"thiserror 1.0.64",
|
||||
"thiserror 2.0.3",
|
||||
"v8",
|
||||
]
|
||||
|
||||
|
@ -8506,9 +8530,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "v8"
|
||||
version = "130.0.2"
|
||||
version = "130.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ee0be58935708fa4d7efb970c6cf9f2d9511d24ee24246481a65b6ee167348d"
|
||||
checksum = "a511192602f7b435b0a241c1947aa743eb7717f20a9195f4b5e8ed1952e01db1"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"bitflags 2.6.0",
|
||||
|
@ -8706,11 +8730,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm_dep_analyzer"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f270206a91783fd90625c8bb0d8fbd459d0b1d1bf209b656f713f01ae7c04b8"
|
||||
checksum = "2eeee3bdea6257cc36d756fa745a70f9d393571e47d69e0ed97581676a5369ca"
|
||||
dependencies = [
|
||||
"thiserror 1.0.64",
|
||||
"deno_error",
|
||||
"thiserror 2.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
12
Cargo.toml
12
Cargo.toml
|
@ -48,10 +48,10 @@ repository = "https://github.com/denoland/deno"
|
|||
|
||||
[workspace.dependencies]
|
||||
deno_ast = { version = "=0.44.0", features = ["transpiling"] }
|
||||
deno_core = { version = "0.327.0" }
|
||||
deno_core = { version = "0.330.0" }
|
||||
|
||||
deno_bench_util = { version = "0.178.0", path = "./bench_util" }
|
||||
deno_config = { version = "=0.42.0", features = ["workspace", "sync"] }
|
||||
deno_config = { version = "=0.43.0", features = ["workspace", "sync"] }
|
||||
deno_lockfile = "=0.24.0"
|
||||
deno_media_type = { version = "0.2.3", features = ["module_specifier"] }
|
||||
deno_npm = "=0.27.0"
|
||||
|
@ -63,10 +63,10 @@ deno_terminal = "0.2.0"
|
|||
napi_sym = { version = "0.114.0", path = "./ext/napi/sym" }
|
||||
test_util = { package = "test_server", path = "./tests/util/server" }
|
||||
|
||||
denokv_proto = "0.8.4"
|
||||
denokv_remote = "0.8.4"
|
||||
denokv_proto = "0.9.0"
|
||||
denokv_remote = "0.9.0"
|
||||
# denokv_sqlite brings in bundled sqlite if we don't disable the default features
|
||||
denokv_sqlite = { default-features = false, version = "0.8.4" }
|
||||
denokv_sqlite = { default-features = false, version = "0.9.0" }
|
||||
|
||||
# exts
|
||||
deno_broadcast_channel = { version = "0.178.0", path = "./ext/broadcast_channel" }
|
||||
|
@ -119,7 +119,7 @@ dashmap = "5.5.3"
|
|||
data-encoding = "2.3.3"
|
||||
data-url = "=0.3.1"
|
||||
deno_cache_dir = "=0.16.0"
|
||||
deno_error = "=0.5.2"
|
||||
deno_error = "=0.5.3"
|
||||
deno_package_json = { version = "0.4.0", default-features = false }
|
||||
deno_unsync = "0.4.2"
|
||||
dlopen2 = "0.6.1"
|
||||
|
|
|
@ -62,6 +62,7 @@ serde_json.workspace = true
|
|||
zstd.workspace = true
|
||||
glibc_version = "0.1.2"
|
||||
flate2 = { workspace = true, features = ["default"] }
|
||||
deno_error.workspace = true
|
||||
|
||||
[target.'cfg(windows)'.build-dependencies]
|
||||
winapi.workspace = true
|
||||
|
@ -72,9 +73,9 @@ deno_ast = { workspace = true, features = ["bundler", "cjs", "codegen", "proposa
|
|||
deno_cache_dir.workspace = true
|
||||
deno_config.workspace = true
|
||||
deno_core = { workspace = true, features = ["include_js_files_for_snapshotting"] }
|
||||
deno_doc = { version = "=0.161.3", features = ["rust", "comrak"] }
|
||||
deno_doc = { version = "=0.164.0", features = ["rust", "comrak"] }
|
||||
deno_error.workspace = true
|
||||
deno_graph = { version = "=0.86.9" }
|
||||
deno_graph = { version = "=0.87.0" }
|
||||
deno_lint = { version = "=0.68.2", features = ["docs"] }
|
||||
deno_lockfile.workspace = true
|
||||
deno_npm.workspace = true
|
||||
|
@ -124,7 +125,7 @@ http.workspace = true
|
|||
http-body.workspace = true
|
||||
http-body-util.workspace = true
|
||||
hyper-util.workspace = true
|
||||
import_map = { version = "=0.20.1", features = ["ext"] }
|
||||
import_map = { version = "=0.21.0", features = ["ext"] }
|
||||
indexmap.workspace = true
|
||||
jsonc-parser = { workspace = true, features = ["cst", "serde"] }
|
||||
jupyter_runtime = { package = "runtimelib", version = "=0.19.0", features = ["tokio-runtime"] }
|
||||
|
|
|
@ -10,6 +10,7 @@ use deno_core::error::AnyError;
|
|||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::parking_lot::MutexGuard;
|
||||
use deno_core::serde_json;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_lockfile::Lockfile;
|
||||
use deno_lockfile::WorkspaceMemberConfig;
|
||||
use deno_package_json::PackageJsonDepValue;
|
||||
|
@ -59,6 +60,14 @@ impl<'a, T> std::ops::DerefMut for Guard<'a, T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
#[error("Failed writing lockfile")]
|
||||
#[class(inherit)]
|
||||
struct AtomicWriteFileWithRetriesError {
|
||||
#[source]
|
||||
source: std::io::Error,
|
||||
}
|
||||
|
||||
impl CliLockfile {
|
||||
/// Get the inner deno_lockfile::Lockfile.
|
||||
pub fn lock(&self) -> Guard<Lockfile> {
|
||||
|
@ -78,7 +87,7 @@ impl CliLockfile {
|
|||
self.lockfile.lock().overwrite
|
||||
}
|
||||
|
||||
pub fn write_if_changed(&self) -> Result<(), AnyError> {
|
||||
pub fn write_if_changed(&self) -> Result<(), JsErrorBox> {
|
||||
if self.skip_write {
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -96,7 +105,9 @@ impl CliLockfile {
|
|||
&bytes,
|
||||
cache::CACHE_PERM,
|
||||
)
|
||||
.context("Failed writing lockfile.")?;
|
||||
.map_err(|source| {
|
||||
JsErrorBox::from_err(AtomicWriteFileWithRetriesError { source })
|
||||
})?;
|
||||
lockfile.has_content_changed = false;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -255,7 +266,7 @@ impl CliLockfile {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn error_if_changed(&self) -> Result<(), AnyError> {
|
||||
pub fn error_if_changed(&self) -> Result<(), JsErrorBox> {
|
||||
if !self.frozen {
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -267,9 +278,7 @@ impl CliLockfile {
|
|||
let diff = crate::util::diff::diff(&contents, &new_contents);
|
||||
// has an extra newline at the end
|
||||
let diff = diff.trim_end();
|
||||
Err(deno_core::anyhow::anyhow!(
|
||||
"The lockfile is out of date. Run `deno install --frozen=false`, or rerun with `--frozen=false` to update it.\nchanges:\n{diff}"
|
||||
))
|
||||
Err(JsErrorBox::generic(format!("The lockfile is out of date. Run `deno install --frozen=false`, or rerun with `--frozen=false` to update it.\nchanges:\n{diff}")))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ use deno_ast::SourceMapOption;
|
|||
use deno_cache_dir::file_fetcher::CacheSetting;
|
||||
pub use deno_config::deno_json::BenchConfig;
|
||||
pub use deno_config::deno_json::ConfigFile;
|
||||
use deno_config::deno_json::ConfigFileError;
|
||||
use deno_config::deno_json::FmtConfig;
|
||||
pub use deno_config::deno_json::FmtOptionsConfig;
|
||||
use deno_config::deno_json::LintConfig;
|
||||
|
@ -55,6 +56,7 @@ use deno_core::error::AnyError;
|
|||
use deno_core::resolve_url_or_path;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::url::Url;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_graph::GraphKind;
|
||||
pub use deno_json::check_warn_tsconfig;
|
||||
use deno_lint::linter::LintConfig as DenoLintConfig;
|
||||
|
@ -604,7 +606,8 @@ pub fn create_default_npmrc() -> Arc<ResolvedNpmRc> {
|
|||
})
|
||||
}
|
||||
|
||||
#[derive(Error, Debug, Clone)]
|
||||
#[derive(Error, Debug, Clone, deno_error::JsError)]
|
||||
#[class(generic)]
|
||||
pub enum RootCertStoreLoadError {
|
||||
#[error(
|
||||
"Unknown certificate store \"{0}\" specified (allowed: \"system,mozilla\")"
|
||||
|
@ -1104,7 +1107,7 @@ impl CliOptions {
|
|||
pkg_json_dep_resolution,
|
||||
specified_import_map: cli_arg_specified_import_map,
|
||||
},
|
||||
|path| Ok(std::fs::read_to_string(path)?),
|
||||
|path| std::fs::read_to_string(path).map_err(JsErrorBox::from_err),
|
||||
)?)
|
||||
}
|
||||
|
||||
|
@ -1246,11 +1249,14 @@ impl CliOptions {
|
|||
|
||||
pub fn node_modules_dir(
|
||||
&self,
|
||||
) -> Result<Option<NodeModulesDirMode>, AnyError> {
|
||||
) -> Result<
|
||||
Option<NodeModulesDirMode>,
|
||||
deno_config::deno_json::NodeModulesDirParseError,
|
||||
> {
|
||||
if let Some(flag) = self.flags.node_modules_dir {
|
||||
return Ok(Some(flag));
|
||||
}
|
||||
self.workspace().node_modules_dir().map_err(Into::into)
|
||||
self.workspace().node_modules_dir()
|
||||
}
|
||||
|
||||
pub fn vendor_dir_path(&self) -> Option<&PathBuf> {
|
||||
|
@ -1260,7 +1266,7 @@ impl CliOptions {
|
|||
pub fn resolve_ts_config_for_emit(
|
||||
&self,
|
||||
config_type: TsConfigType,
|
||||
) -> Result<TsConfigForEmit, AnyError> {
|
||||
) -> Result<TsConfigForEmit, ConfigFileError> {
|
||||
self.workspace().resolve_ts_config_for_emit(config_type)
|
||||
}
|
||||
|
||||
|
@ -1289,7 +1295,7 @@ impl CliOptions {
|
|||
|
||||
pub fn to_compiler_option_types(
|
||||
&self,
|
||||
) -> Result<Vec<deno_graph::ReferrerImports>, AnyError> {
|
||||
) -> Result<Vec<deno_graph::ReferrerImports>, serde_json::Error> {
|
||||
self
|
||||
.workspace()
|
||||
.to_compiler_option_types()
|
||||
|
|
18
cli/build.rs
18
cli/build.rs
|
@ -13,10 +13,9 @@ mod ts {
|
|||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use deno_core::error::custom_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op2;
|
||||
use deno_core::OpState;
|
||||
use deno_error::JsErrorBox;
|
||||
use serde::Serialize;
|
||||
|
||||
use super::*;
|
||||
|
@ -53,7 +52,7 @@ mod ts {
|
|||
fn op_script_version(
|
||||
_state: &mut OpState,
|
||||
#[string] _arg: &str,
|
||||
) -> Result<Option<String>, AnyError> {
|
||||
) -> Result<Option<String>, JsErrorBox> {
|
||||
Ok(Some("1".to_string()))
|
||||
}
|
||||
|
||||
|
@ -72,7 +71,7 @@ mod ts {
|
|||
fn op_load(
|
||||
state: &mut OpState,
|
||||
#[string] load_specifier: &str,
|
||||
) -> Result<LoadResponse, AnyError> {
|
||||
) -> Result<LoadResponse, JsErrorBox> {
|
||||
let op_crate_libs = state.borrow::<HashMap<&str, PathBuf>>();
|
||||
let path_dts = state.borrow::<PathBuf>();
|
||||
let re_asset = lazy_regex::regex!(r"asset:/{3}lib\.(\S+)\.d\.ts");
|
||||
|
@ -93,12 +92,15 @@ mod ts {
|
|||
// if it comes from an op crate, we were supplied with the path to the
|
||||
// file.
|
||||
let path = if let Some(op_crate_lib) = op_crate_libs.get(lib) {
|
||||
PathBuf::from(op_crate_lib).canonicalize()?
|
||||
PathBuf::from(op_crate_lib)
|
||||
.canonicalize()
|
||||
.map_err(JsErrorBox::from_err)?
|
||||
// otherwise we will generate the path ourself
|
||||
} else {
|
||||
path_dts.join(format!("lib.{lib}.d.ts"))
|
||||
};
|
||||
let data = std::fs::read_to_string(path)?;
|
||||
let data =
|
||||
std::fs::read_to_string(path).map_err(JsErrorBox::from_err)?;
|
||||
Ok(LoadResponse {
|
||||
data,
|
||||
version: "1".to_string(),
|
||||
|
@ -106,13 +108,13 @@ mod ts {
|
|||
script_kind: 3,
|
||||
})
|
||||
} else {
|
||||
Err(custom_error(
|
||||
Err(JsErrorBox::new(
|
||||
"InvalidSpecifier",
|
||||
format!("An invalid specifier was requested: {}", load_specifier),
|
||||
))
|
||||
}
|
||||
} else {
|
||||
Err(custom_error(
|
||||
Err(JsErrorBox::new(
|
||||
"InvalidSpecifier",
|
||||
format!("An invalid specifier was requested: {}", load_specifier),
|
||||
))
|
||||
|
|
17
cli/cache/mod.rs
vendored
17
cli/cache/mod.rs
vendored
|
@ -8,7 +8,6 @@ use deno_ast::MediaType;
|
|||
use deno_cache_dir::file_fetcher::CacheSetting;
|
||||
use deno_cache_dir::file_fetcher::FetchNoFollowErrorKind;
|
||||
use deno_cache_dir::file_fetcher::FileOrRedirect;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures;
|
||||
use deno_core::futures::FutureExt;
|
||||
use deno_core::ModuleSpecifier;
|
||||
|
@ -62,6 +61,7 @@ pub type GlobalHttpCache = deno_cache_dir::GlobalHttpCache<CliSys>;
|
|||
pub type LocalHttpCache = deno_cache_dir::LocalHttpCache<CliSys>;
|
||||
pub type LocalLspHttpCache = deno_cache_dir::LocalLspHttpCache<CliSys>;
|
||||
pub use deno_cache_dir::HttpCache;
|
||||
use deno_error::JsErrorBox;
|
||||
|
||||
pub struct FetchCacherOptions {
|
||||
pub file_header_overrides: HashMap<ModuleSpecifier, HashMap<String, String>>,
|
||||
|
@ -194,9 +194,9 @@ impl Loader for FetchCacher {
|
|||
LoaderCacheSetting::Use => None,
|
||||
LoaderCacheSetting::Reload => {
|
||||
if matches!(file_fetcher.cache_setting(), CacheSetting::Only) {
|
||||
return Err(deno_core::anyhow::anyhow!(
|
||||
return Err(deno_graph::source::LoadError::Other(Arc::new(JsErrorBox::generic(
|
||||
"Could not resolve version constraint using only cached data. Try running again without --cached-only"
|
||||
));
|
||||
))));
|
||||
}
|
||||
Some(CacheSetting::ReloadAll)
|
||||
}
|
||||
|
@ -262,28 +262,27 @@ impl Loader for FetchCacher {
|
|||
FetchNoFollowErrorKind::CacheSave { .. } |
|
||||
FetchNoFollowErrorKind::UnsupportedScheme { .. } |
|
||||
FetchNoFollowErrorKind::RedirectHeaderParse { .. } |
|
||||
FetchNoFollowErrorKind::InvalidHeader { .. } => Err(AnyError::from(err)),
|
||||
FetchNoFollowErrorKind::InvalidHeader { .. } => Err(deno_graph::source::LoadError::Other(Arc::new(JsErrorBox::from_err(err)))),
|
||||
FetchNoFollowErrorKind::NotCached { .. } => {
|
||||
if options.cache_setting == LoaderCacheSetting::Only {
|
||||
Ok(None)
|
||||
} else {
|
||||
Err(AnyError::from(err))
|
||||
Err(deno_graph::source::LoadError::Other(Arc::new(JsErrorBox::from_err(err))))
|
||||
}
|
||||
},
|
||||
FetchNoFollowErrorKind::ChecksumIntegrity(err) => {
|
||||
// convert to the equivalent deno_graph error so that it
|
||||
// enhances it if this is passed to deno_graph
|
||||
Err(
|
||||
deno_graph::source::ChecksumIntegrityError {
|
||||
deno_graph::source::LoadError::ChecksumIntegrity(deno_graph::source::ChecksumIntegrityError {
|
||||
actual: err.actual,
|
||||
expected: err.expected,
|
||||
}
|
||||
.into(),
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
CliFetchNoFollowErrorKind::PermissionCheck(permission_check_error) => Err(AnyError::from(permission_check_error)),
|
||||
CliFetchNoFollowErrorKind::PermissionCheck(permission_check_error) => Err(deno_graph::source::LoadError::Other(Arc::new(JsErrorBox::from_err(permission_check_error)))),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
48
cli/emit.rs
48
cli/emit.rs
|
@ -11,10 +11,12 @@ use deno_ast::SourceRangedForSpanned;
|
|||
use deno_ast::TranspileModuleOptions;
|
||||
use deno_ast::TranspileResult;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::error::CoreError;
|
||||
use deno_core::futures::stream::FuturesUnordered;
|
||||
use deno_core::futures::FutureExt;
|
||||
use deno_core::futures::StreamExt;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_graph::MediaType;
|
||||
use deno_graph::Module;
|
||||
use deno_graph::ModuleGraph;
|
||||
|
@ -124,7 +126,7 @@ impl Emitter {
|
|||
let transpiled_source = deno_core::unsync::spawn_blocking({
|
||||
let specifier = specifier.clone();
|
||||
let source = source.clone();
|
||||
move || -> Result<_, AnyError> {
|
||||
move || {
|
||||
EmitParsedSourceHelper::transpile(
|
||||
&parsed_source_cache,
|
||||
&specifier,
|
||||
|
@ -155,7 +157,7 @@ impl Emitter {
|
|||
media_type: MediaType,
|
||||
module_kind: deno_ast::ModuleKind,
|
||||
source: &Arc<str>,
|
||||
) -> Result<String, AnyError> {
|
||||
) -> Result<String, EmitParsedSourceHelperError> {
|
||||
// Note: keep this in sync with the async version above
|
||||
let helper = EmitParsedSourceHelper(self);
|
||||
match helper.pre_emit_parsed_source(specifier, module_kind, source) {
|
||||
|
@ -210,7 +212,7 @@ impl Emitter {
|
|||
pub async fn load_and_emit_for_hmr(
|
||||
&self,
|
||||
specifier: &ModuleSpecifier,
|
||||
) -> Result<String, AnyError> {
|
||||
) -> Result<String, CoreError> {
|
||||
let media_type = MediaType::from_specifier(specifier);
|
||||
let source_code = tokio::fs::read_to_string(
|
||||
ModuleSpecifier::to_file_path(specifier).unwrap(),
|
||||
|
@ -225,17 +227,21 @@ impl Emitter {
|
|||
let source_arc: Arc<str> = source_code.into();
|
||||
let parsed_source = self
|
||||
.parsed_source_cache
|
||||
.remove_or_parse_module(specifier, source_arc, media_type)?;
|
||||
.remove_or_parse_module(specifier, source_arc, media_type)
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
// HMR doesn't work with embedded source maps for some reason, so set
|
||||
// the option to not use them (though you should test this out because
|
||||
// this statement is probably wrong)
|
||||
let mut options = self.transpile_and_emit_options.1.clone();
|
||||
options.source_map = SourceMapOption::None;
|
||||
let is_cjs = self.cjs_tracker.is_cjs_with_known_is_script(
|
||||
specifier,
|
||||
media_type,
|
||||
parsed_source.compute_is_script(),
|
||||
)?;
|
||||
let is_cjs = self
|
||||
.cjs_tracker
|
||||
.is_cjs_with_known_is_script(
|
||||
specifier,
|
||||
media_type,
|
||||
parsed_source.compute_is_script(),
|
||||
)
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
let transpiled_source = parsed_source
|
||||
.transpile(
|
||||
&self.transpile_and_emit_options.0,
|
||||
|
@ -243,7 +249,8 @@ impl Emitter {
|
|||
module_kind: Some(ModuleKind::from_is_cjs(is_cjs)),
|
||||
},
|
||||
&options,
|
||||
)?
|
||||
)
|
||||
.map_err(JsErrorBox::from_err)?
|
||||
.into_source();
|
||||
Ok(transpiled_source.text)
|
||||
}
|
||||
|
@ -282,6 +289,19 @@ enum PreEmitResult {
|
|||
NotCached { source_hash: u64 },
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum EmitParsedSourceHelperError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
ParseDiagnostic(#[from] deno_ast::ParseDiagnostic),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Transpile(#[from] deno_ast::TranspileError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Other(#[from] JsErrorBox),
|
||||
}
|
||||
|
||||
/// Helper to share code between async and sync emit_parsed_source methods.
|
||||
struct EmitParsedSourceHelper<'a>(&'a Emitter);
|
||||
|
||||
|
@ -311,7 +331,7 @@ impl<'a> EmitParsedSourceHelper<'a> {
|
|||
source: Arc<str>,
|
||||
transpile_options: &deno_ast::TranspileOptions,
|
||||
emit_options: &deno_ast::EmitOptions,
|
||||
) -> Result<EmittedSourceText, AnyError> {
|
||||
) -> Result<EmittedSourceText, EmitParsedSourceHelperError> {
|
||||
// nothing else needs the parsed source at this point, so remove from
|
||||
// the cache in order to not transpile owned
|
||||
let parsed_source = parsed_source_cache
|
||||
|
@ -351,7 +371,7 @@ impl<'a> EmitParsedSourceHelper<'a> {
|
|||
// todo(dsherret): this is a temporary measure until we have swc erroring for this
|
||||
fn ensure_no_import_assertion(
|
||||
parsed_source: &deno_ast::ParsedSource,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), JsErrorBox> {
|
||||
fn has_import_assertion(text: &str) -> bool {
|
||||
// good enough
|
||||
text.contains(" assert ") && !text.contains(" with ")
|
||||
|
@ -360,7 +380,7 @@ fn ensure_no_import_assertion(
|
|||
fn create_err(
|
||||
parsed_source: &deno_ast::ParsedSource,
|
||||
range: SourceRange,
|
||||
) -> AnyError {
|
||||
) -> JsErrorBox {
|
||||
let text_info = parsed_source.text_info_lazy();
|
||||
let loc = text_info.line_and_column_display(range.start);
|
||||
let mut msg = "Import assertions are deprecated. Use `with` keyword, instead of 'assert' keyword.".to_string();
|
||||
|
@ -373,7 +393,7 @@ fn ensure_no_import_assertion(
|
|||
loc.line_number,
|
||||
loc.column_number,
|
||||
));
|
||||
deno_core::anyhow::anyhow!("{}", msg)
|
||||
JsErrorBox::generic(msg)
|
||||
}
|
||||
|
||||
let deno_ast::ProgramRef::Module(module) = parsed_source.program_ref() else {
|
||||
|
|
123
cli/errors.rs
123
cli/errors.rs
|
@ -1,123 +0,0 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
//! There are many types of errors in Deno:
|
||||
//! - AnyError: a generic wrapper that can encapsulate any type of error.
|
||||
//! - JsError: a container for the error message and stack trace for exceptions
|
||||
//! thrown in JavaScript code. We use this to pretty-print stack traces.
|
||||
//! - Diagnostic: these are errors that originate in TypeScript's compiler.
|
||||
//! They're similar to JsError, in that they have line numbers. But
|
||||
//! Diagnostics are compile-time type errors, whereas JsErrors are runtime
|
||||
//! exceptions.
|
||||
|
||||
use deno_ast::ParseDiagnostic;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_graph::source::ResolveError;
|
||||
use deno_graph::ModuleError;
|
||||
use deno_graph::ModuleGraphError;
|
||||
use deno_graph::ModuleLoadError;
|
||||
use deno_graph::ResolutionError;
|
||||
use import_map::ImportMapError;
|
||||
|
||||
fn get_import_map_error_class(_: &ImportMapError) -> &'static str {
|
||||
"URIError"
|
||||
}
|
||||
|
||||
fn get_diagnostic_class(_: &ParseDiagnostic) -> &'static str {
|
||||
"SyntaxError"
|
||||
}
|
||||
|
||||
pub fn get_module_graph_error_class(err: &ModuleGraphError) -> &'static str {
|
||||
match err {
|
||||
ModuleGraphError::ResolutionError(err)
|
||||
| ModuleGraphError::TypesResolutionError(err) => {
|
||||
get_resolution_error_class(err)
|
||||
}
|
||||
ModuleGraphError::ModuleError(err) => get_module_error_class(err),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_module_error_class(err: &ModuleError) -> &'static str {
|
||||
use deno_graph::JsrLoadError;
|
||||
use deno_graph::NpmLoadError;
|
||||
|
||||
match err {
|
||||
ModuleError::InvalidTypeAssertion { .. } => "SyntaxError",
|
||||
ModuleError::ParseErr(_, diagnostic) => get_diagnostic_class(diagnostic),
|
||||
ModuleError::WasmParseErr(..) => "SyntaxError",
|
||||
ModuleError::UnsupportedMediaType { .. }
|
||||
| ModuleError::UnsupportedImportAttributeType { .. } => "TypeError",
|
||||
ModuleError::Missing(_, _) | ModuleError::MissingDynamic(_, _) => {
|
||||
"NotFound"
|
||||
}
|
||||
ModuleError::LoadingErr(_, _, err) => match err {
|
||||
ModuleLoadError::Loader(err) => get_error_class_name(err.as_ref()),
|
||||
ModuleLoadError::HttpsChecksumIntegrity(_)
|
||||
| ModuleLoadError::TooManyRedirects => "Error",
|
||||
ModuleLoadError::NodeUnknownBuiltinModule(_) => "NotFound",
|
||||
ModuleLoadError::Decode(_) => "TypeError",
|
||||
ModuleLoadError::Npm(err) => match err {
|
||||
NpmLoadError::NotSupportedEnvironment
|
||||
| NpmLoadError::PackageReqResolution(_)
|
||||
| NpmLoadError::RegistryInfo(_) => "Error",
|
||||
NpmLoadError::PackageReqReferenceParse(_) => "TypeError",
|
||||
},
|
||||
ModuleLoadError::Jsr(err) => match err {
|
||||
JsrLoadError::UnsupportedManifestChecksum
|
||||
| JsrLoadError::PackageFormat(_) => "TypeError",
|
||||
JsrLoadError::ContentLoadExternalSpecifier
|
||||
| JsrLoadError::ContentLoad(_)
|
||||
| JsrLoadError::ContentChecksumIntegrity(_)
|
||||
| JsrLoadError::PackageManifestLoad(_, _)
|
||||
| JsrLoadError::PackageVersionManifestChecksumIntegrity(..)
|
||||
| JsrLoadError::PackageVersionManifestLoad(_, _)
|
||||
| JsrLoadError::RedirectInPackage(_) => "Error",
|
||||
JsrLoadError::PackageNotFound(_)
|
||||
| JsrLoadError::PackageReqNotFound(_)
|
||||
| JsrLoadError::PackageVersionNotFound(_)
|
||||
| JsrLoadError::UnknownExport { .. } => "NotFound",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn get_resolution_error_class(err: &ResolutionError) -> &'static str {
|
||||
match err {
|
||||
ResolutionError::ResolverError { error, .. } => {
|
||||
use ResolveError::*;
|
||||
match error.as_ref() {
|
||||
Specifier(_) => "TypeError",
|
||||
Other(e) => get_error_class_name(e),
|
||||
}
|
||||
}
|
||||
_ => "TypeError",
|
||||
}
|
||||
}
|
||||
|
||||
fn get_try_from_int_error_class(_: &std::num::TryFromIntError) -> &'static str {
|
||||
"TypeError"
|
||||
}
|
||||
|
||||
pub fn get_error_class_name(e: &AnyError) -> &'static str {
|
||||
deno_runtime::errors::get_error_class_name(e)
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<ImportMapError>()
|
||||
.map(get_import_map_error_class)
|
||||
})
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<ParseDiagnostic>()
|
||||
.map(get_diagnostic_class)
|
||||
})
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<ModuleGraphError>()
|
||||
.map(get_module_graph_error_class)
|
||||
})
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<ResolutionError>()
|
||||
.map(get_resolution_error_class)
|
||||
})
|
||||
.or_else(|| {
|
||||
e.downcast_ref::<std::num::TryFromIntError>()
|
||||
.map(get_try_from_int_error_class)
|
||||
})
|
||||
.unwrap_or("Error")
|
||||
}
|
|
@ -10,6 +10,7 @@ use deno_config::workspace::WorkspaceResolver;
|
|||
use deno_core::error::AnyError;
|
||||
use deno_core::futures::FutureExt;
|
||||
use deno_core::FeatureChecker;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_resolver::cjs::IsCjsResolutionMode;
|
||||
use deno_resolver::npm::NpmReqResolverOptions;
|
||||
use deno_resolver::DenoResolverOptions;
|
||||
|
@ -118,7 +119,7 @@ impl CliRootCertStoreProvider {
|
|||
}
|
||||
|
||||
impl RootCertStoreProvider for CliRootCertStoreProvider {
|
||||
fn get_or_try_init(&self) -> Result<&RootCertStore, AnyError> {
|
||||
fn get_or_try_init(&self) -> Result<&RootCertStore, JsErrorBox> {
|
||||
self
|
||||
.cell
|
||||
.get_or_try_init(|| {
|
||||
|
@ -128,7 +129,7 @@ impl RootCertStoreProvider for CliRootCertStoreProvider {
|
|||
self.maybe_ca_data.clone(),
|
||||
)
|
||||
})
|
||||
.map_err(|e| e.into())
|
||||
.map_err(JsErrorBox::from_err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,17 +2,18 @@
|
|||
|
||||
use std::collections::HashSet;
|
||||
use std::error::Error;
|
||||
use std::ops::Deref;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_config::deno_json;
|
||||
use deno_config::deno_json::JsxImportSourceConfig;
|
||||
use deno_config::workspace::JsrPackageConfig;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::error::custom_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_error::JsErrorClass;
|
||||
use deno_graph::source::Loader;
|
||||
use deno_graph::source::LoaderChecksum;
|
||||
use deno_graph::source::ResolutionKind;
|
||||
|
@ -49,8 +50,6 @@ use crate::cache::GlobalHttpCache;
|
|||
use crate::cache::ModuleInfoCache;
|
||||
use crate::cache::ParsedSourceCache;
|
||||
use crate::colors;
|
||||
use crate::errors::get_error_class_name;
|
||||
use crate::errors::get_module_graph_error_class;
|
||||
use crate::file_fetcher::CliFileFetcher;
|
||||
use crate::npm::CliNpmResolver;
|
||||
use crate::resolver::CjsTracker;
|
||||
|
@ -59,6 +58,7 @@ use crate::resolver::CliSloppyImportsResolver;
|
|||
use crate::resolver::SloppyImportsCachedFs;
|
||||
use crate::sys::CliSys;
|
||||
use crate::tools::check;
|
||||
use crate::tools::check::CheckError;
|
||||
use crate::tools::check::TypeChecker;
|
||||
use crate::util::file_watcher::WatcherCommunicator;
|
||||
use crate::util::fs::canonicalize_path;
|
||||
|
@ -85,7 +85,7 @@ pub fn graph_valid(
|
|||
sys: &CliSys,
|
||||
roots: &[ModuleSpecifier],
|
||||
options: GraphValidOptions,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), JsErrorBox> {
|
||||
if options.exit_integrity_errors {
|
||||
graph_exit_integrity_errors(graph);
|
||||
}
|
||||
|
@ -104,9 +104,9 @@ pub fn graph_valid(
|
|||
} else {
|
||||
// finally surface the npm resolution result
|
||||
if let Err(err) = &graph.npm_dep_graph_result {
|
||||
return Err(custom_error(
|
||||
get_error_class_name(err),
|
||||
format_deno_graph_error(err.as_ref().deref()),
|
||||
return Err(JsErrorBox::new(
|
||||
err.get_class(),
|
||||
format_deno_graph_error(err),
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
|
@ -145,7 +145,7 @@ pub fn graph_walk_errors<'a>(
|
|||
sys: &'a CliSys,
|
||||
roots: &'a [ModuleSpecifier],
|
||||
options: GraphWalkErrorsOptions,
|
||||
) -> impl Iterator<Item = AnyError> + 'a {
|
||||
) -> impl Iterator<Item = JsErrorBox> + 'a {
|
||||
graph
|
||||
.walk(
|
||||
roots.iter(),
|
||||
|
@ -197,7 +197,7 @@ pub fn graph_walk_errors<'a>(
|
|||
return None;
|
||||
}
|
||||
|
||||
Some(custom_error(get_module_graph_error_class(&error), message))
|
||||
Some(JsErrorBox::new(error.get_class(), message))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -437,14 +437,14 @@ impl ModuleGraphCreator {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn graph_valid(&self, graph: &ModuleGraph) -> Result<(), AnyError> {
|
||||
pub fn graph_valid(&self, graph: &ModuleGraph) -> Result<(), JsErrorBox> {
|
||||
self.module_graph_builder.graph_valid(graph)
|
||||
}
|
||||
|
||||
async fn type_check_graph(
|
||||
&self,
|
||||
graph: ModuleGraph,
|
||||
) -> Result<Arc<ModuleGraph>, AnyError> {
|
||||
) -> Result<Arc<ModuleGraph>, CheckError> {
|
||||
self
|
||||
.type_checker
|
||||
.check(
|
||||
|
@ -467,6 +467,27 @@ pub struct BuildFastCheckGraphOptions<'a> {
|
|||
pub workspace_fast_check: deno_graph::WorkspaceFastCheckOption<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum BuildGraphWithNpmResolutionError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
SerdeJson(#[from] serde_json::Error),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
ToMaybeJsxImportSourceConfig(
|
||||
#[from] deno_json::ToMaybeJsxImportSourceConfigError,
|
||||
),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
NodeModulesDirParse(#[from] deno_json::NodeModulesDirParseError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Other(#[from] JsErrorBox),
|
||||
#[class(generic)]
|
||||
#[error("Resolving npm specifier entrypoints this way is currently not supported with \"nodeModules\": \"manual\". In the meantime, try with --node-modules-dir=auto instead")]
|
||||
UnsupportedNpmSpecifierEntrypointResolutionWay,
|
||||
}
|
||||
|
||||
pub struct ModuleGraphBuilder {
|
||||
caches: Arc<cache::Caches>,
|
||||
cjs_tracker: Arc<CjsTracker>,
|
||||
|
@ -524,7 +545,7 @@ impl ModuleGraphBuilder {
|
|||
&self,
|
||||
graph: &mut ModuleGraph,
|
||||
options: CreateGraphOptions<'a>,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), BuildGraphWithNpmResolutionError> {
|
||||
enum MutLoaderRef<'a> {
|
||||
Borrowed(&'a mut dyn Loader),
|
||||
Owned(cache::FetchCacher),
|
||||
|
@ -652,7 +673,7 @@ impl ModuleGraphBuilder {
|
|||
loader: &'a mut dyn deno_graph::source::Loader,
|
||||
options: deno_graph::BuildOptions<'a>,
|
||||
npm_caching: NpmCachingStrategy,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), BuildGraphWithNpmResolutionError> {
|
||||
// ensure an "npm install" is done if the user has explicitly
|
||||
// opted into using a node_modules directory
|
||||
if self
|
||||
|
@ -689,7 +710,7 @@ impl ModuleGraphBuilder {
|
|||
if roots.iter().any(|r| r.scheme() == "npm")
|
||||
&& self.npm_resolver.as_byonm().is_some()
|
||||
{
|
||||
bail!("Resolving npm specifier entrypoints this way is currently not supported with \"nodeModules\": \"manual\". In the meantime, try with --node-modules-dir=auto instead");
|
||||
return Err(BuildGraphWithNpmResolutionError::UnsupportedNpmSpecifierEntrypointResolutionWay);
|
||||
}
|
||||
|
||||
graph.build(roots, loader, options).await;
|
||||
|
@ -740,7 +761,7 @@ impl ModuleGraphBuilder {
|
|||
&self,
|
||||
graph: &mut ModuleGraph,
|
||||
options: BuildFastCheckGraphOptions,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), deno_json::ToMaybeJsxImportSourceConfigError> {
|
||||
if !graph.graph_kind().include_types() {
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -804,7 +825,7 @@ impl ModuleGraphBuilder {
|
|||
/// Check if `roots` and their deps are available. Returns `Ok(())` if
|
||||
/// so. Returns `Err(_)` if there is a known module graph or resolution
|
||||
/// error statically reachable from `roots` and not a dynamic import.
|
||||
pub fn graph_valid(&self, graph: &ModuleGraph) -> Result<(), AnyError> {
|
||||
pub fn graph_valid(&self, graph: &ModuleGraph) -> Result<(), JsErrorBox> {
|
||||
self.graph_roots_valid(
|
||||
graph,
|
||||
&graph.roots.iter().cloned().collect::<Vec<_>>(),
|
||||
|
@ -815,7 +836,7 @@ impl ModuleGraphBuilder {
|
|||
&self,
|
||||
graph: &ModuleGraph,
|
||||
roots: &[ModuleSpecifier],
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), JsErrorBox> {
|
||||
graph_valid(
|
||||
graph,
|
||||
&self.sys,
|
||||
|
@ -832,7 +853,10 @@ impl ModuleGraphBuilder {
|
|||
)
|
||||
}
|
||||
|
||||
fn create_graph_resolver(&self) -> Result<CliGraphResolver, AnyError> {
|
||||
fn create_graph_resolver(
|
||||
&self,
|
||||
) -> Result<CliGraphResolver, deno_json::ToMaybeJsxImportSourceConfigError>
|
||||
{
|
||||
let jsx_import_source_config = self
|
||||
.cli_options
|
||||
.workspace()
|
||||
|
@ -1001,8 +1025,13 @@ fn get_resolution_error_bare_specifier(
|
|||
Some(specifier.as_str())
|
||||
} else if let ResolutionError::ResolverError { error, .. } = error {
|
||||
if let ResolveError::Other(error) = (*error).as_ref() {
|
||||
if let Some(ImportMapError::UnmappedBareSpecifier(specifier, _)) =
|
||||
error.downcast_ref::<ImportMapError>()
|
||||
if let Some(import_map::ImportMapErrorKind::UnmappedBareSpecifier(
|
||||
specifier,
|
||||
_,
|
||||
)) = error
|
||||
.as_any()
|
||||
.downcast_ref::<ImportMapError>()
|
||||
.map(|e| &**e)
|
||||
{
|
||||
Some(specifier.as_str())
|
||||
} else {
|
||||
|
@ -1039,11 +1068,12 @@ fn get_import_prefix_missing_error(error: &ResolutionError) -> Option<&str> {
|
|||
ResolveError::Other(other_error) => {
|
||||
if let Some(SpecifierError::ImportPrefixMissing {
|
||||
specifier, ..
|
||||
}) = other_error.downcast_ref::<SpecifierError>()
|
||||
}) = other_error.as_any().downcast_ref::<SpecifierError>()
|
||||
{
|
||||
maybe_specifier = Some(specifier);
|
||||
}
|
||||
}
|
||||
ResolveError::ImportMap(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1294,7 +1324,7 @@ mod test {
|
|||
let specifier = ModuleSpecifier::parse("file:///file.ts").unwrap();
|
||||
let err = import_map.resolve(input, &specifier).err().unwrap();
|
||||
let err = ResolutionError::ResolverError {
|
||||
error: Arc::new(ResolveError::Other(err.into())),
|
||||
error: Arc::new(ResolveError::Other(JsErrorBox::from_err(err))),
|
||||
specifier: input.to_string(),
|
||||
range: Range {
|
||||
specifier,
|
||||
|
|
|
@ -6,13 +6,14 @@ use std::thread::ThreadId;
|
|||
|
||||
use boxed_error::Boxed;
|
||||
use deno_cache_dir::file_fetcher::RedirectHeaderParseError;
|
||||
use deno_core::error::custom_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures::StreamExt;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::serde;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::url::Url;
|
||||
use deno_error::JsError;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_runtime::deno_fetch;
|
||||
use deno_runtime::deno_fetch::create_http_client;
|
||||
use deno_runtime::deno_fetch::CreateHttpClientOptions;
|
||||
|
@ -94,34 +95,49 @@ impl HttpClientProvider {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
#[derive(Debug, Error, JsError)]
|
||||
#[class(type)]
|
||||
#[error("Bad response: {:?}{}", .status_code, .response_text.as_ref().map(|s| format!("\n\n{}", s)).unwrap_or_else(String::new))]
|
||||
pub struct BadResponseError {
|
||||
pub status_code: StatusCode,
|
||||
pub response_text: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Boxed)]
|
||||
#[derive(Debug, Boxed, JsError)]
|
||||
pub struct DownloadError(pub Box<DownloadErrorKind>);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
#[derive(Debug, Error, JsError)]
|
||||
pub enum DownloadErrorKind {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Fetch(AnyError),
|
||||
Fetch(deno_fetch::ClientSendError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
UrlParse(#[from] deno_core::url::ParseError),
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
HttpParse(#[from] http::Error),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Json(#[from] serde_json::Error),
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
ToStr(#[from] http::header::ToStrError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
RedirectHeaderParse(RedirectHeaderParseError),
|
||||
#[class(type)]
|
||||
#[error("Too many redirects.")]
|
||||
TooManyRedirects,
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
BadResponse(#[from] BadResponseError),
|
||||
#[class("Http")]
|
||||
#[error("Not Found.")]
|
||||
NotFound,
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Other(JsErrorBox),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -208,11 +224,11 @@ impl HttpClient {
|
|||
Ok(String::from_utf8(bytes)?)
|
||||
}
|
||||
|
||||
pub async fn download(&self, url: Url) -> Result<Vec<u8>, AnyError> {
|
||||
pub async fn download(&self, url: Url) -> Result<Vec<u8>, DownloadError> {
|
||||
let maybe_bytes = self.download_inner(url, None, None).await?;
|
||||
match maybe_bytes {
|
||||
Some(bytes) => Ok(bytes),
|
||||
None => Err(custom_error("Http", "Not found.")),
|
||||
None => Err(DownloadErrorKind::NotFound.into_box()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -276,7 +292,7 @@ impl HttpClient {
|
|||
get_response_body_with_progress(response, progress_guard)
|
||||
.await
|
||||
.map(|(_, body)| Some(body))
|
||||
.map_err(|err| DownloadErrorKind::Fetch(err).into_box())
|
||||
.map_err(|err| DownloadErrorKind::Other(err).into_box())
|
||||
}
|
||||
|
||||
async fn get_redirected_response(
|
||||
|
@ -293,7 +309,7 @@ impl HttpClient {
|
|||
.clone()
|
||||
.send(req)
|
||||
.await
|
||||
.map_err(|e| DownloadErrorKind::Fetch(e.into()).into_box())?;
|
||||
.map_err(|e| DownloadErrorKind::Fetch(e).into_box())?;
|
||||
let status = response.status();
|
||||
if status.is_redirection() {
|
||||
for _ in 0..5 {
|
||||
|
@ -313,7 +329,7 @@ impl HttpClient {
|
|||
.clone()
|
||||
.send(req)
|
||||
.await
|
||||
.map_err(|e| DownloadErrorKind::Fetch(e.into()).into_box())?;
|
||||
.map_err(|e| DownloadErrorKind::Fetch(e).into_box())?;
|
||||
let status = new_response.status();
|
||||
if status.is_redirection() {
|
||||
response = new_response;
|
||||
|
@ -332,7 +348,7 @@ impl HttpClient {
|
|||
pub async fn get_response_body_with_progress(
|
||||
response: http::Response<deno_fetch::ResBody>,
|
||||
progress_guard: Option<&UpdateGuard>,
|
||||
) -> Result<(HeaderMap, Vec<u8>), AnyError> {
|
||||
) -> Result<(HeaderMap, Vec<u8>), JsErrorBox> {
|
||||
use http_body::Body as _;
|
||||
if let Some(progress_guard) = progress_guard {
|
||||
let mut total_size = response.body().size_hint().exact();
|
||||
|
|
|
@ -10,13 +10,13 @@ use deno_ast::SourceRange;
|
|||
use deno_ast::SourceRangedForSpanned;
|
||||
use deno_ast::SourceTextInfo;
|
||||
use deno_config::workspace::MappedResolution;
|
||||
use deno_core::error::custom_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::serde::Deserialize;
|
||||
use deno_core::serde::Serialize;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_lint::diagnostic::LintDiagnosticRange;
|
||||
use deno_path_util::url_to_file_path;
|
||||
use deno_runtime::deno_node::PathClean;
|
||||
|
@ -1070,10 +1070,13 @@ impl CodeActionCollection {
|
|||
// we wrap tsc, we can't handle the asynchronous response, so it is
|
||||
// actually easier to return errors if we ever encounter one of these,
|
||||
// which we really wouldn't expect from the Deno lsp.
|
||||
return Err(custom_error(
|
||||
"UnsupportedFix",
|
||||
"The action returned from TypeScript is unsupported.",
|
||||
));
|
||||
return Err(
|
||||
JsErrorBox::new(
|
||||
"UnsupportedFix",
|
||||
"The action returned from TypeScript is unsupported.",
|
||||
)
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
let Some(action) =
|
||||
fix_ts_import_action(specifier, resolution_mode, action, language_server)
|
||||
|
|
|
@ -41,6 +41,7 @@ use deno_core::serde_json::json;
|
|||
use deno_core::serde_json::Value;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_lint::linter::LintConfig as DenoLintConfig;
|
||||
use deno_npm::npm_rc::ResolvedNpmRc;
|
||||
use deno_package_json::PackageJsonCache;
|
||||
|
@ -1575,7 +1576,7 @@ impl ConfigData {
|
|||
pkg_json_dep_resolution,
|
||||
specified_import_map,
|
||||
},
|
||||
|path| Ok(std::fs::read_to_string(path)?),
|
||||
|path| std::fs::read_to_string(path).map_err(JsErrorBox::from_err),
|
||||
)
|
||||
.inspect_err(|err| {
|
||||
lsp_warn!(
|
||||
|
|
|
@ -34,7 +34,7 @@ use deno_semver::jsr::JsrPackageReqReference;
|
|||
use deno_semver::npm::NpmPackageReqReference;
|
||||
use deno_semver::package::PackageReq;
|
||||
use import_map::ImportMap;
|
||||
use import_map::ImportMapError;
|
||||
use import_map::ImportMapErrorKind;
|
||||
use log::error;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::sync::Mutex;
|
||||
|
@ -1297,8 +1297,8 @@ impl DenoDiagnostic {
|
|||
let mut message;
|
||||
message = enhanced_resolution_error_message(err);
|
||||
if let deno_graph::ResolutionError::ResolverError {error, ..} = err{
|
||||
if let ResolveError::Other(resolve_error, ..) = (*error).as_ref() {
|
||||
if let Some(ImportMapError::UnmappedBareSpecifier(specifier, _)) = resolve_error.downcast_ref::<ImportMapError>() {
|
||||
if let ResolveError::ImportMap(importmap) = (*error).as_ref() {
|
||||
if let ImportMapErrorKind::UnmappedBareSpecifier(specifier, _) = &**importmap {
|
||||
if specifier.chars().next().unwrap_or('\0') == '@'{
|
||||
let hint = format!("\nHint: Use [deno add {}] to add the dependency.", specifier);
|
||||
message.push_str(hint.as_str());
|
||||
|
|
|
@ -18,13 +18,13 @@ use deno_ast::swc::visit::VisitWith;
|
|||
use deno_ast::MediaType;
|
||||
use deno_ast::ParsedSource;
|
||||
use deno_ast::SourceTextInfo;
|
||||
use deno_core::error::custom_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures::future;
|
||||
use deno_core::futures::future::Shared;
|
||||
use deno_core::futures::FutureExt;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_graph::Resolution;
|
||||
use deno_path_util::url_to_file_path;
|
||||
use deno_runtime::deno_node;
|
||||
|
@ -1081,7 +1081,7 @@ impl Documents {
|
|||
.or_else(|| self.file_system_docs.remove_document(specifier))
|
||||
.map(Ok)
|
||||
.unwrap_or_else(|| {
|
||||
Err(custom_error(
|
||||
Err(JsErrorBox::new(
|
||||
"NotFound",
|
||||
format!("The specifier \"{specifier}\" was not found."),
|
||||
))
|
||||
|
|
|
@ -122,7 +122,7 @@ use crate::util::sync::AsyncFlag;
|
|||
struct LspRootCertStoreProvider(RootCertStore);
|
||||
|
||||
impl RootCertStoreProvider for LspRootCertStoreProvider {
|
||||
fn get_or_try_init(&self) -> Result<&RootCertStore, AnyError> {
|
||||
fn get_or_try_init(&self) -> Result<&RootCertStore, deno_error::JsErrorBox> {
|
||||
Ok(&self.0)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use deno_core::error::custom_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_error::JsErrorBox;
|
||||
use dissimilar::diff;
|
||||
use dissimilar::Chunk;
|
||||
use text_size::TextRange;
|
||||
|
@ -137,7 +137,7 @@ impl LineIndex {
|
|||
if let Some(line_offset) = self.utf8_offsets.get(position.line as usize) {
|
||||
Ok(line_offset + col)
|
||||
} else {
|
||||
Err(custom_error("OutOfRange", "The position is out of range."))
|
||||
Err(JsErrorBox::new("OutOfRange", "The position is out of range.").into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -157,7 +157,7 @@ impl LineIndex {
|
|||
if let Some(line_offset) = self.utf16_offsets.get(position.line as usize) {
|
||||
Ok(line_offset + TextSize::from(position.character))
|
||||
} else {
|
||||
Err(custom_error("OutOfRange", "The position is out of range."))
|
||||
Err(JsErrorBox::new("OutOfRange", "The position is out of range.").into())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ use deno_core::anyhow::Context as _;
|
|||
use deno_core::convert::Smi;
|
||||
use deno_core::convert::ToV8;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::error::StdAnyError;
|
||||
use deno_core::futures::stream::FuturesOrdered;
|
||||
use deno_core::futures::FutureExt;
|
||||
use deno_core::futures::StreamExt;
|
||||
|
@ -4331,7 +4330,7 @@ impl TscSpecifierMap {
|
|||
pub fn normalize<S: AsRef<str>>(
|
||||
&self,
|
||||
specifier: S,
|
||||
) -> Result<ModuleSpecifier, AnyError> {
|
||||
) -> Result<ModuleSpecifier, deno_core::url::ParseError> {
|
||||
let original = specifier.as_ref();
|
||||
if let Some(specifier) = self.normalized_specifiers.get(original) {
|
||||
return Ok(specifier.clone());
|
||||
|
@ -4339,7 +4338,7 @@ impl TscSpecifierMap {
|
|||
let specifier_str = original.replace(".d.ts.d.ts", ".d.ts");
|
||||
let specifier = match ModuleSpecifier::parse(&specifier_str) {
|
||||
Ok(s) => s,
|
||||
Err(err) => return Err(err.into()),
|
||||
Err(err) => return Err(err),
|
||||
};
|
||||
if specifier.as_str() != original {
|
||||
self
|
||||
|
@ -4437,6 +4436,16 @@ fn op_is_node_file(state: &mut OpState, #[string] path: String) -> bool {
|
|||
r
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
enum LoadError {
|
||||
#[error("{0}")]
|
||||
#[class(inherit)]
|
||||
UrlParse(#[from] deno_core::url::ParseError),
|
||||
#[error("{0}")]
|
||||
#[class(inherit)]
|
||||
SerdeV8(#[from] serde_v8::Error),
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct LoadResponse {
|
||||
|
@ -4451,7 +4460,7 @@ fn op_load<'s>(
|
|||
scope: &'s mut v8::HandleScope,
|
||||
state: &mut OpState,
|
||||
#[string] specifier: &str,
|
||||
) -> Result<v8::Local<'s, v8::Value>, AnyError> {
|
||||
) -> Result<v8::Local<'s, v8::Value>, LoadError> {
|
||||
let state = state.borrow_mut::<State>();
|
||||
let mark = state
|
||||
.performance
|
||||
|
@ -4482,7 +4491,7 @@ fn op_load<'s>(
|
|||
fn op_release(
|
||||
state: &mut OpState,
|
||||
#[string] specifier: &str,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), deno_core::url::ParseError> {
|
||||
let state = state.borrow_mut::<State>();
|
||||
let mark = state
|
||||
.performance
|
||||
|
@ -4499,7 +4508,7 @@ fn op_resolve(
|
|||
state: &mut OpState,
|
||||
#[string] base: String,
|
||||
#[serde] specifiers: Vec<(bool, String)>,
|
||||
) -> Result<Vec<Option<(String, String)>>, AnyError> {
|
||||
) -> Result<Vec<Option<(String, String)>>, deno_core::url::ParseError> {
|
||||
op_resolve_inner(state, ResolveArgs { base, specifiers })
|
||||
}
|
||||
|
||||
|
@ -4511,7 +4520,7 @@ struct TscRequestArray {
|
|||
}
|
||||
|
||||
impl<'a> ToV8<'a> for TscRequestArray {
|
||||
type Error = StdAnyError;
|
||||
type Error = serde_v8::Error;
|
||||
|
||||
fn to_v8(
|
||||
self,
|
||||
|
@ -4526,9 +4535,7 @@ impl<'a> ToV8<'a> for TscRequestArray {
|
|||
.unwrap()
|
||||
.into();
|
||||
let args = args.unwrap_or_else(|| v8::Array::new(scope, 0).into());
|
||||
let scope_url = serde_v8::to_v8(scope, self.scope)
|
||||
.map_err(AnyError::from)
|
||||
.map_err(StdAnyError::from)?;
|
||||
let scope_url = serde_v8::to_v8(scope, self.scope)?;
|
||||
|
||||
let change = self.change.to_v8(scope).unwrap_infallible();
|
||||
|
||||
|
@ -4586,7 +4593,7 @@ async fn op_poll_requests(
|
|||
fn op_resolve_inner(
|
||||
state: &mut OpState,
|
||||
args: ResolveArgs,
|
||||
) -> Result<Vec<Option<(String, String)>>, AnyError> {
|
||||
) -> Result<Vec<Option<(String, String)>>, deno_core::url::ParseError> {
|
||||
let state = state.borrow_mut::<State>();
|
||||
let mark = state.performance.mark_with_args("tsc.op.op_resolve", &args);
|
||||
let referrer = state.specifier_map.normalize(&args.base)?;
|
||||
|
@ -4743,7 +4750,7 @@ fn op_script_names(state: &mut OpState) -> ScriptNames {
|
|||
fn op_script_version(
|
||||
state: &mut OpState,
|
||||
#[string] specifier: &str,
|
||||
) -> Result<Option<String>, AnyError> {
|
||||
) -> Result<Option<String>, deno_core::url::ParseError> {
|
||||
let state = state.borrow_mut::<State>();
|
||||
let mark = state.performance.mark("tsc.op.op_script_version");
|
||||
let specifier = state.specifier_map.normalize(specifier)?;
|
||||
|
@ -5398,7 +5405,8 @@ impl TscRequest {
|
|||
fn to_server_request<'s>(
|
||||
&self,
|
||||
scope: &mut v8::HandleScope<'s>,
|
||||
) -> Result<(&'static str, Option<v8::Local<'s, v8::Value>>), AnyError> {
|
||||
) -> Result<(&'static str, Option<v8::Local<'s, v8::Value>>), serde_v8::Error>
|
||||
{
|
||||
let args = match self {
|
||||
TscRequest::GetDiagnostics(args) => {
|
||||
("$getDiagnostics", Some(serde_v8::to_v8(scope, args)?))
|
||||
|
|
13
cli/main.rs
13
cli/main.rs
|
@ -4,7 +4,6 @@ mod args;
|
|||
mod cache;
|
||||
mod cdp;
|
||||
mod emit;
|
||||
mod errors;
|
||||
mod factory;
|
||||
mod file_fetcher;
|
||||
mod graph_container;
|
||||
|
@ -38,7 +37,7 @@ use std::sync::Arc;
|
|||
use args::TaskFlags;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::error::JsError;
|
||||
use deno_core::error::CoreError;
|
||||
use deno_core::futures::FutureExt;
|
||||
use deno_core::unsync::JoinHandle;
|
||||
use deno_npm::resolution::SnapshotFromLockfileError;
|
||||
|
@ -202,7 +201,7 @@ async fn run_subcommand(flags: Arc<Flags>) -> Result<i32, AnyError> {
|
|||
match result {
|
||||
Ok(v) => Ok(v),
|
||||
Err(script_err) => {
|
||||
if let Some(ResolvePkgFolderFromDenoReqError::Byonm(ByonmResolvePkgFolderFromDenoReqError::UnmatchedReq(_))) = script_err.downcast_ref::<ResolvePkgFolderFromDenoReqError>() {
|
||||
if let Some(ResolvePkgFolderFromDenoReqError::Byonm(ByonmResolvePkgFolderFromDenoReqError::UnmatchedReq(_))) = util::result::any_and_jserrorbox_downcast_ref::<ResolvePkgFolderFromDenoReqError>(&script_err) {
|
||||
if flags.node_modules_dir.is_none() {
|
||||
let mut flags = flags.deref().clone();
|
||||
let watch = match &flags.subcommand {
|
||||
|
@ -373,10 +372,14 @@ fn exit_for_error(error: AnyError) -> ! {
|
|||
let mut error_string = format!("{error:?}");
|
||||
let mut error_code = 1;
|
||||
|
||||
if let Some(e) = error.downcast_ref::<JsError>() {
|
||||
if let Some(CoreError::Js(e)) =
|
||||
util::result::any_and_jserrorbox_downcast_ref::<CoreError>(&error)
|
||||
{
|
||||
error_string = format_js_error(e);
|
||||
} else if let Some(SnapshotFromLockfileError::IntegrityCheckFailed(e)) =
|
||||
error.downcast_ref::<SnapshotFromLockfileError>()
|
||||
util::result::any_and_jserrorbox_downcast_ref::<SnapshotFromLockfileError>(
|
||||
&error,
|
||||
)
|
||||
{
|
||||
error_string = e.to_string();
|
||||
error_code = 10;
|
||||
|
|
|
@ -10,7 +10,6 @@ mod standalone;
|
|||
mod args;
|
||||
mod cache;
|
||||
mod emit;
|
||||
mod errors;
|
||||
mod file_fetcher;
|
||||
mod http_util;
|
||||
mod js;
|
||||
|
@ -30,8 +29,8 @@ use std::env;
|
|||
use std::env::current_exe;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::error::CoreError;
|
||||
use deno_core::error::JsError;
|
||||
use deno_runtime::fmt_errors::format_js_error;
|
||||
use deno_runtime::tokio_util::create_and_run_current_thread_with_maybe_metrics;
|
||||
|
@ -41,6 +40,7 @@ use indexmap::IndexMap;
|
|||
use standalone::DenoCompileFileSystem;
|
||||
|
||||
use crate::args::Flags;
|
||||
use crate::util::result::any_and_jserrorbox_downcast_ref;
|
||||
|
||||
pub(crate) fn unstable_exit_cb(feature: &str, api_name: &str) {
|
||||
log::error!(
|
||||
|
@ -65,8 +65,10 @@ fn unwrap_or_exit<T>(result: Result<T, AnyError>) -> T {
|
|||
Err(error) => {
|
||||
let mut error_string = format!("{:?}", error);
|
||||
|
||||
if let Some(e) = error.downcast_ref::<JsError>() {
|
||||
error_string = format_js_error(e);
|
||||
if let Some(CoreError::Js(js_error)) =
|
||||
any_and_jserrorbox_downcast_ref::<CoreError>(&error)
|
||||
{
|
||||
error_string = format_js_error(js_error);
|
||||
}
|
||||
|
||||
exit_with_message(&error_string, 1);
|
||||
|
|
|
@ -14,11 +14,9 @@ use std::sync::Arc;
|
|||
use deno_ast::MediaType;
|
||||
use deno_ast::ModuleKind;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::custom_error;
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::error::ModuleLoaderError;
|
||||
use deno_core::futures::future::FutureExt;
|
||||
use deno_core::futures::Future;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
|
@ -31,6 +29,8 @@ use deno_core::ModuleSpecifier;
|
|||
use deno_core::ModuleType;
|
||||
use deno_core::RequestedModuleType;
|
||||
use deno_core::SourceCodeCacheInfo;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_error::JsErrorClass;
|
||||
use deno_graph::GraphKind;
|
||||
use deno_graph::JsModule;
|
||||
use deno_graph::JsonModule;
|
||||
|
@ -59,7 +59,6 @@ use crate::cache::CodeCache;
|
|||
use crate::cache::FastInsecureHasher;
|
||||
use crate::cache::ParsedSourceCache;
|
||||
use crate::emit::Emitter;
|
||||
use crate::errors::get_module_error_class;
|
||||
use crate::graph_container::MainModuleGraphContainer;
|
||||
use crate::graph_container::ModuleGraphContainer;
|
||||
use crate::graph_container::ModuleGraphUpdatePermit;
|
||||
|
@ -79,6 +78,7 @@ use crate::resolver::NotSupportedKindInNpmError;
|
|||
use crate::resolver::NpmModuleLoader;
|
||||
use crate::sys::CliSys;
|
||||
use crate::tools::check;
|
||||
use crate::tools::check::CheckError;
|
||||
use crate::tools::check::TypeChecker;
|
||||
use crate::util::progress_bar::ProgressBar;
|
||||
use crate::util::text_encoding::code_without_source_map;
|
||||
|
@ -86,6 +86,21 @@ use crate::util::text_encoding::source_map_from_code;
|
|||
use crate::worker::CreateModuleLoaderResult;
|
||||
use crate::worker::ModuleLoaderFactory;
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum PrepareModuleLoadError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
BuildGraphWithNpmResolution(
|
||||
#[from] crate::graph_util::BuildGraphWithNpmResolutionError,
|
||||
),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Check(#[from] CheckError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Other(#[from] JsErrorBox),
|
||||
}
|
||||
|
||||
pub struct ModuleLoadPreparer {
|
||||
options: Arc<CliOptions>,
|
||||
lockfile: Option<Arc<CliLockfile>>,
|
||||
|
@ -125,7 +140,7 @@ impl ModuleLoadPreparer {
|
|||
lib: TsTypeLib,
|
||||
permissions: PermissionsContainer,
|
||||
ext_overwrite: Option<&String>,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), PrepareModuleLoadError> {
|
||||
log::debug!("Preparing module load.");
|
||||
let _pb_clear_guard = self.progress_bar.clear_guard();
|
||||
|
||||
|
@ -206,7 +221,7 @@ impl ModuleLoadPreparer {
|
|||
&self,
|
||||
graph: &ModuleGraph,
|
||||
roots: &[ModuleSpecifier],
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), JsErrorBox> {
|
||||
self.module_graph_builder.graph_roots_valid(graph, roots)
|
||||
}
|
||||
}
|
||||
|
@ -423,7 +438,7 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||
specifier: &ModuleSpecifier,
|
||||
maybe_referrer: Option<&ModuleSpecifier>,
|
||||
requested_module_type: RequestedModuleType,
|
||||
) -> Result<ModuleSource, AnyError> {
|
||||
) -> Result<ModuleSource, ModuleLoaderError> {
|
||||
let code_source = self.load_code_source(specifier, maybe_referrer).await?;
|
||||
let code = if self.shared.is_inspecting
|
||||
|| code_source.media_type == MediaType::Wasm
|
||||
|
@ -446,7 +461,7 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||
if module_type == ModuleType::Json
|
||||
&& requested_module_type != RequestedModuleType::Json
|
||||
{
|
||||
return Err(generic_error("Attempted to load JSON module without specifying \"type\": \"json\" attribute in the import statement."));
|
||||
return Err(JsErrorBox::generic("Attempted to load JSON module without specifying \"type\": \"json\" attribute in the import statement.").into());
|
||||
}
|
||||
|
||||
let code_cache = if module_type == ModuleType::JavaScript {
|
||||
|
@ -507,7 +522,7 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||
fn resolve_referrer(
|
||||
&self,
|
||||
referrer: &str,
|
||||
) -> Result<ModuleSpecifier, AnyError> {
|
||||
) -> Result<ModuleSpecifier, ModuleLoaderError> {
|
||||
let referrer = if referrer.is_empty() && self.shared.is_repl {
|
||||
// FIXME(bartlomieju): this is a hacky way to provide compatibility with REPL
|
||||
// and `Deno.core.evalContext` API. Ideally we should always have a referrer filled
|
||||
|
@ -533,7 +548,7 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||
&self,
|
||||
raw_specifier: &str,
|
||||
referrer: &ModuleSpecifier,
|
||||
) -> Result<ModuleSpecifier, AnyError> {
|
||||
) -> Result<ModuleSpecifier, ModuleLoaderError> {
|
||||
let graph = self.graph_container.graph();
|
||||
let resolution = match graph.get(referrer) {
|
||||
Some(Module::Js(module)) => module
|
||||
|
@ -547,19 +562,25 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||
let specifier = match resolution {
|
||||
Resolution::Ok(resolved) => Cow::Borrowed(&resolved.specifier),
|
||||
Resolution::Err(err) => {
|
||||
return Err(custom_error(
|
||||
"TypeError",
|
||||
format!("{}\n", err.to_string_with_range()),
|
||||
));
|
||||
return Err(
|
||||
JsErrorBox::type_error(format!("{}\n", err.to_string_with_range()))
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
Resolution::None => Cow::Owned(self.shared.resolver.resolve(
|
||||
raw_specifier,
|
||||
referrer,
|
||||
deno_graph::Position::zeroed(),
|
||||
// if we're here, that means it's resolving a dynamic import
|
||||
ResolutionMode::Import,
|
||||
NodeResolutionKind::Execution,
|
||||
)?),
|
||||
Resolution::None => Cow::Owned(
|
||||
self
|
||||
.shared
|
||||
.resolver
|
||||
.resolve(
|
||||
raw_specifier,
|
||||
referrer,
|
||||
deno_graph::Position::zeroed(),
|
||||
// if we're here, that means it's resolving a dynamic import
|
||||
ResolutionMode::Import,
|
||||
NodeResolutionKind::Execution,
|
||||
)
|
||||
.map_err(JsErrorBox::from_err)?,
|
||||
),
|
||||
};
|
||||
|
||||
if self.shared.is_repl {
|
||||
|
@ -574,7 +595,7 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||
ResolutionMode::Import,
|
||||
NodeResolutionKind::Execution,
|
||||
)
|
||||
.map_err(AnyError::from);
|
||||
.map_err(|e| JsErrorBox::from_err(e).into());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -585,7 +606,8 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||
.npm_resolver
|
||||
.as_managed()
|
||||
.unwrap() // byonm won't create a Module::Npm
|
||||
.resolve_pkg_folder_from_deno_module(module.nv_reference.nv())?;
|
||||
.resolve_pkg_folder_from_deno_module(module.nv_reference.nv())
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
self
|
||||
.shared
|
||||
.node_resolver
|
||||
|
@ -701,7 +723,7 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||
&self,
|
||||
graph: &'graph ModuleGraph,
|
||||
specifier: &ModuleSpecifier,
|
||||
) -> Result<Option<CodeOrDeferredEmit<'graph>>, AnyError> {
|
||||
) -> Result<Option<CodeOrDeferredEmit<'graph>>, JsErrorBox> {
|
||||
if specifier.scheme() == "node" {
|
||||
// Node built-in modules should be handled internally.
|
||||
unreachable!("Deno bug. {} was misconfigured internally.", specifier);
|
||||
|
@ -710,8 +732,8 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||
let maybe_module = match graph.try_get(specifier) {
|
||||
Ok(module) => module,
|
||||
Err(err) => {
|
||||
return Err(custom_error(
|
||||
get_module_error_class(err),
|
||||
return Err(JsErrorBox::new(
|
||||
err.get_class(),
|
||||
enhance_graph_error(
|
||||
&self.shared.sys,
|
||||
&ModuleGraphError::ModuleError(err.clone()),
|
||||
|
@ -739,11 +761,12 @@ impl<TGraphContainer: ModuleGraphContainer>
|
|||
is_script,
|
||||
..
|
||||
})) => {
|
||||
if self.shared.cjs_tracker.is_cjs_with_known_is_script(
|
||||
specifier,
|
||||
*media_type,
|
||||
*is_script,
|
||||
)? {
|
||||
if self
|
||||
.shared
|
||||
.cjs_tracker
|
||||
.is_cjs_with_known_is_script(specifier, *media_type, *is_script)
|
||||
.map_err(JsErrorBox::from_err)?
|
||||
{
|
||||
return Ok(Some(CodeOrDeferredEmit::Cjs {
|
||||
specifier,
|
||||
media_type: *media_type,
|
||||
|
@ -875,16 +898,16 @@ impl<TGraphContainer: ModuleGraphContainer> ModuleLoader
|
|||
specifier: &str,
|
||||
referrer: &str,
|
||||
_kind: deno_core::ResolutionKind,
|
||||
) -> Result<ModuleSpecifier, AnyError> {
|
||||
) -> Result<ModuleSpecifier, ModuleLoaderError> {
|
||||
fn ensure_not_jsr_non_jsr_remote_import(
|
||||
specifier: &ModuleSpecifier,
|
||||
referrer: &ModuleSpecifier,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), JsErrorBox> {
|
||||
if referrer.as_str().starts_with(jsr_url().as_str())
|
||||
&& !specifier.as_str().starts_with(jsr_url().as_str())
|
||||
&& matches!(specifier.scheme(), "http" | "https")
|
||||
{
|
||||
bail!("Importing {} blocked. JSR packages cannot import non-JSR remote modules for security reasons.", specifier);
|
||||
return Err(JsErrorBox::generic(format!("Importing {} blocked. JSR packages cannot import non-JSR remote modules for security reasons.", specifier)));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -937,7 +960,7 @@ impl<TGraphContainer: ModuleGraphContainer> ModuleLoader
|
|||
specifier: &ModuleSpecifier,
|
||||
_maybe_referrer: Option<String>,
|
||||
is_dynamic: bool,
|
||||
) -> Pin<Box<dyn Future<Output = Result<(), AnyError>>>> {
|
||||
) -> Pin<Box<dyn Future<Output = Result<(), ModuleLoaderError>>>> {
|
||||
self.0.shared.in_flight_loads_tracker.increase();
|
||||
if self.0.shared.in_npm_pkg_checker.in_npm_package(specifier) {
|
||||
return Box::pin(deno_core::futures::future::ready(Ok(())));
|
||||
|
@ -986,7 +1009,8 @@ impl<TGraphContainer: ModuleGraphContainer> ModuleLoader
|
|||
permissions,
|
||||
None,
|
||||
)
|
||||
.await?;
|
||||
.await
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
update_permit.commit();
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1130,35 +1154,37 @@ impl<TGraphContainer: ModuleGraphContainer> NodeRequireLoader
|
|||
&self,
|
||||
permissions: &mut dyn deno_runtime::deno_node::NodePermissions,
|
||||
path: &'a Path,
|
||||
) -> Result<std::borrow::Cow<'a, Path>, AnyError> {
|
||||
) -> Result<Cow<'a, Path>, JsErrorBox> {
|
||||
if let Ok(url) = deno_path_util::url_from_file_path(path) {
|
||||
// allow reading if it's in the module graph
|
||||
if self.graph_container.graph().get(&url).is_some() {
|
||||
return Ok(std::borrow::Cow::Borrowed(path));
|
||||
return Ok(Cow::Borrowed(path));
|
||||
}
|
||||
}
|
||||
self
|
||||
.npm_registry_permission_checker
|
||||
.ensure_read_permission(permissions, path)
|
||||
.map_err(JsErrorBox::from_err)
|
||||
}
|
||||
|
||||
fn load_text_file_lossy(
|
||||
&self,
|
||||
path: &Path,
|
||||
) -> Result<Cow<'static, str>, AnyError> {
|
||||
) -> Result<Cow<'static, str>, JsErrorBox> {
|
||||
// todo(dsherret): use the preloaded module from the graph if available?
|
||||
let media_type = MediaType::from_path(path);
|
||||
let text = self.sys.fs_read_to_string_lossy(path)?;
|
||||
let text = self
|
||||
.sys
|
||||
.fs_read_to_string_lossy(path)
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
if media_type.is_emittable() {
|
||||
let specifier = deno_path_util::url_from_file_path(path)?;
|
||||
let specifier = deno_path_util::url_from_file_path(path)
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
if self.in_npm_pkg_checker.in_npm_package(&specifier) {
|
||||
return Err(
|
||||
NotSupportedKindInNpmError {
|
||||
media_type,
|
||||
specifier,
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
return Err(JsErrorBox::from_err(NotSupportedKindInNpmError {
|
||||
media_type,
|
||||
specifier,
|
||||
}));
|
||||
}
|
||||
self
|
||||
.emitter
|
||||
|
@ -1172,6 +1198,7 @@ impl<TGraphContainer: ModuleGraphContainer> NodeRequireLoader
|
|||
&text.into(),
|
||||
)
|
||||
.map(Cow::Owned)
|
||||
.map_err(JsErrorBox::from_err)
|
||||
} else {
|
||||
Ok(text)
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ use deno_core::anyhow::Context;
|
|||
use deno_core::error::AnyError;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::url::Url;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_npm::npm_rc::ResolvedNpmRc;
|
||||
use deno_npm::registry::NpmPackageInfo;
|
||||
use deno_npm::registry::NpmRegistryApi;
|
||||
|
@ -322,6 +323,28 @@ impl std::fmt::Debug for ManagedCliNpmResolver {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum ResolvePkgFolderFromPkgIdError {
|
||||
#[class(inherit)]
|
||||
#[error("{0}")]
|
||||
NpmPackageFsResolverPackageFolder(
|
||||
#[from] resolvers::NpmPackageFsResolverPackageFolderError,
|
||||
),
|
||||
#[class(inherit)]
|
||||
#[error("{0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum ResolvePkgFolderFromDenoModuleError {
|
||||
#[class(inherit)]
|
||||
#[error("{0}")]
|
||||
PackageNvNotFound(#[from] deno_npm::resolution::PackageNvNotFoundError),
|
||||
#[class(inherit)]
|
||||
#[error("{0}")]
|
||||
ResolvePkgFolderFromPkgId(#[from] ResolvePkgFolderFromPkgIdError),
|
||||
}
|
||||
|
||||
impl ManagedCliNpmResolver {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
|
@ -356,7 +379,7 @@ impl ManagedCliNpmResolver {
|
|||
pub fn resolve_pkg_folder_from_pkg_id(
|
||||
&self,
|
||||
pkg_id: &NpmPackageId,
|
||||
) -> Result<PathBuf, AnyError> {
|
||||
) -> Result<PathBuf, ResolvePkgFolderFromPkgIdError> {
|
||||
let path = self.fs_resolver.package_folder(pkg_id)?;
|
||||
let path = canonicalize_path_maybe_not_exists(&self.sys, &path)?;
|
||||
log::debug!(
|
||||
|
@ -423,7 +446,7 @@ impl ManagedCliNpmResolver {
|
|||
pub async fn add_and_cache_package_reqs(
|
||||
&self,
|
||||
packages: &[PackageReq],
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), JsErrorBox> {
|
||||
self
|
||||
.add_package_reqs_raw(
|
||||
packages,
|
||||
|
@ -436,7 +459,7 @@ impl ManagedCliNpmResolver {
|
|||
pub async fn add_package_reqs_no_cache(
|
||||
&self,
|
||||
packages: &[PackageReq],
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), JsErrorBox> {
|
||||
self
|
||||
.add_package_reqs_raw(packages, None)
|
||||
.await
|
||||
|
@ -447,7 +470,7 @@ impl ManagedCliNpmResolver {
|
|||
&self,
|
||||
packages: &[PackageReq],
|
||||
caching: PackageCaching<'_>,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), JsErrorBox> {
|
||||
self
|
||||
.add_package_reqs_raw(packages, Some(caching))
|
||||
.await
|
||||
|
@ -517,7 +540,7 @@ impl ManagedCliNpmResolver {
|
|||
|
||||
pub async fn inject_synthetic_types_node_package(
|
||||
&self,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), JsErrorBox> {
|
||||
let reqs = &[PackageReq::from_str("@types/node").unwrap()];
|
||||
// add and ensure this isn't added to the lockfile
|
||||
self
|
||||
|
@ -530,16 +553,16 @@ impl ManagedCliNpmResolver {
|
|||
pub async fn cache_packages(
|
||||
&self,
|
||||
caching: PackageCaching<'_>,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), JsErrorBox> {
|
||||
self.fs_resolver.cache_packages(caching).await
|
||||
}
|
||||
|
||||
pub fn resolve_pkg_folder_from_deno_module(
|
||||
&self,
|
||||
nv: &PackageNv,
|
||||
) -> Result<PathBuf, AnyError> {
|
||||
) -> Result<PathBuf, ResolvePkgFolderFromDenoModuleError> {
|
||||
let pkg_id = self.resolution.resolve_pkg_id_from_deno_module(nv)?;
|
||||
self.resolve_pkg_folder_from_pkg_id(&pkg_id)
|
||||
Ok(self.resolve_pkg_folder_from_pkg_id(&pkg_id)?)
|
||||
}
|
||||
|
||||
pub fn resolve_pkg_id_from_pkg_req(
|
||||
|
@ -580,7 +603,7 @@ impl ManagedCliNpmResolver {
|
|||
/// return value of `false` means that new packages were added to the NPM resolution.
|
||||
pub async fn ensure_top_level_package_json_install(
|
||||
&self,
|
||||
) -> Result<bool, AnyError> {
|
||||
) -> Result<bool, JsErrorBox> {
|
||||
if !self.top_level_install_flag.raise() {
|
||||
return Ok(true); // already did this
|
||||
}
|
||||
|
@ -687,12 +710,12 @@ impl CliNpmReqResolver for ManagedCliNpmResolver {
|
|||
req: &PackageReq,
|
||||
_referrer: &ModuleSpecifier,
|
||||
) -> Result<PathBuf, ResolvePkgFolderFromDenoReqError> {
|
||||
let pkg_id = self
|
||||
.resolve_pkg_id_from_pkg_req(req)
|
||||
.map_err(|err| ResolvePkgFolderFromDenoReqError::Managed(err.into()))?;
|
||||
let pkg_id = self.resolve_pkg_id_from_pkg_req(req).map_err(|err| {
|
||||
ResolvePkgFolderFromDenoReqError::Managed(Box::new(err))
|
||||
})?;
|
||||
self
|
||||
.resolve_pkg_folder_from_pkg_id(&pkg_id)
|
||||
.map_err(ResolvePkgFolderFromDenoReqError::Managed)
|
||||
.map_err(|err| ResolvePkgFolderFromDenoReqError::Managed(Box::new(err)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ use std::sync::Arc;
|
|||
|
||||
use capacity_builder::StringBuilder;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_lockfile::NpmPackageDependencyLockfileInfo;
|
||||
use deno_lockfile::NpmPackageLockfileInfo;
|
||||
use deno_npm::registry::NpmRegistryApi;
|
||||
|
@ -39,7 +40,7 @@ pub struct AddPkgReqsResult {
|
|||
/// package requirements.
|
||||
pub results: Vec<Result<PackageNv, NpmResolutionError>>,
|
||||
/// The final result of resolving and caching all the package requirements.
|
||||
pub dependencies_result: Result<(), AnyError>,
|
||||
pub dependencies_result: Result<(), JsErrorBox>,
|
||||
}
|
||||
|
||||
/// Handles updating and storing npm resolution in memory where the underlying
|
||||
|
@ -106,7 +107,7 @@ impl NpmResolution {
|
|||
*snapshot_lock.write() = snapshot;
|
||||
Ok(())
|
||||
}
|
||||
Err(err) => Err(err.into()),
|
||||
Err(err) => Err(JsErrorBox::from_err(err)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,13 +8,18 @@ use std::path::PathBuf;
|
|||
|
||||
use async_trait::async_trait;
|
||||
use deno_ast::ModuleSpecifier;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_npm::NpmPackageCacheFolderId;
|
||||
use deno_npm::NpmPackageId;
|
||||
use node_resolver::errors::PackageFolderResolveError;
|
||||
|
||||
use super::super::PackageCaching;
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
#[class(generic)]
|
||||
#[error("Package folder not found for '{0}'")]
|
||||
pub struct NpmPackageFsResolverPackageFolderError(deno_semver::StackString);
|
||||
|
||||
/// Part of the resolution that interacts with the file system.
|
||||
#[async_trait(?Send)]
|
||||
pub trait NpmPackageFsResolver: Send + Sync {
|
||||
|
@ -26,12 +31,9 @@ pub trait NpmPackageFsResolver: Send + Sync {
|
|||
fn package_folder(
|
||||
&self,
|
||||
package_id: &NpmPackageId,
|
||||
) -> Result<PathBuf, AnyError> {
|
||||
) -> Result<PathBuf, NpmPackageFsResolverPackageFolderError> {
|
||||
self.maybe_package_folder(package_id).ok_or_else(|| {
|
||||
deno_core::anyhow::anyhow!(
|
||||
"Package folder not found for '{}'",
|
||||
package_id.as_serialized()
|
||||
)
|
||||
NpmPackageFsResolverPackageFolderError(package_id.as_serialized())
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -44,10 +46,10 @@ pub trait NpmPackageFsResolver: Send + Sync {
|
|||
fn resolve_package_cache_folder_id_from_specifier(
|
||||
&self,
|
||||
specifier: &ModuleSpecifier,
|
||||
) -> Result<Option<NpmPackageCacheFolderId>, AnyError>;
|
||||
) -> Result<Option<NpmPackageCacheFolderId>, std::io::Error>;
|
||||
|
||||
async fn cache_packages<'a>(
|
||||
&self,
|
||||
caching: PackageCaching<'a>,
|
||||
) -> Result<(), AnyError>;
|
||||
) -> Result<(), JsErrorBox>;
|
||||
}
|
||||
|
|
|
@ -6,8 +6,6 @@ use std::collections::VecDeque;
|
|||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_npm::resolution::NpmResolutionSnapshot;
|
||||
use deno_npm::NpmPackageId;
|
||||
|
||||
|
@ -50,6 +48,48 @@ pub fn warn_missing_entrypoint(
|
|||
);
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum BinEntriesError {
|
||||
#[class(inherit)]
|
||||
#[error("Creating '{path}'")]
|
||||
Creating {
|
||||
path: PathBuf,
|
||||
#[source]
|
||||
#[inherit]
|
||||
source: std::io::Error,
|
||||
},
|
||||
#[cfg(unix)]
|
||||
#[class(inherit)]
|
||||
#[error("Setting permissions on '{path}'")]
|
||||
Permissions {
|
||||
path: PathBuf,
|
||||
#[source]
|
||||
#[inherit]
|
||||
source: std::io::Error,
|
||||
},
|
||||
#[class(inherit)]
|
||||
#[error("Can't set up '{name}' bin at {path}")]
|
||||
SetUpBin {
|
||||
name: String,
|
||||
path: PathBuf,
|
||||
#[source]
|
||||
#[inherit]
|
||||
source: Box<Self>,
|
||||
},
|
||||
#[cfg(unix)]
|
||||
#[class(inherit)]
|
||||
#[error("Setting permissions on '{path}'")]
|
||||
RemoveBinSymlink {
|
||||
path: PathBuf,
|
||||
#[source]
|
||||
#[inherit]
|
||||
source: std::io::Error,
|
||||
},
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Io(#[from] std::io::Error),
|
||||
}
|
||||
|
||||
impl<'a> BinEntries<'a> {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
|
@ -92,15 +132,15 @@ impl<'a> BinEntries<'a> {
|
|||
mut already_seen: impl FnMut(
|
||||
&Path,
|
||||
&str, // bin script
|
||||
) -> Result<(), AnyError>,
|
||||
) -> Result<(), BinEntriesError>,
|
||||
mut new: impl FnMut(
|
||||
&NpmResolutionPackage,
|
||||
&Path,
|
||||
&str, // bin name
|
||||
&str, // bin script
|
||||
) -> Result<(), AnyError>,
|
||||
) -> Result<(), BinEntriesError>,
|
||||
mut filter: impl FnMut(&NpmResolutionPackage) -> bool,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), BinEntriesError> {
|
||||
if !self.collisions.is_empty() && !self.sorted {
|
||||
// walking the dependency tree to find out the depth of each package
|
||||
// is sort of expensive, so we only do it if there's a collision
|
||||
|
@ -168,11 +208,14 @@ impl<'a> BinEntries<'a> {
|
|||
bin_node_modules_dir_path: &Path,
|
||||
filter: impl FnMut(&NpmResolutionPackage) -> bool,
|
||||
mut handler: impl FnMut(&EntrySetupOutcome<'_>),
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), BinEntriesError> {
|
||||
if !self.entries.is_empty() && !bin_node_modules_dir_path.exists() {
|
||||
std::fs::create_dir_all(bin_node_modules_dir_path).with_context(
|
||||
|| format!("Creating '{}'", bin_node_modules_dir_path.display()),
|
||||
)?;
|
||||
std::fs::create_dir_all(bin_node_modules_dir_path).map_err(|source| {
|
||||
BinEntriesError::Creating {
|
||||
path: bin_node_modules_dir_path.to_path_buf(),
|
||||
source,
|
||||
}
|
||||
})?;
|
||||
}
|
||||
|
||||
self.for_each_entry(
|
||||
|
@ -209,7 +252,7 @@ impl<'a> BinEntries<'a> {
|
|||
snapshot: &NpmResolutionSnapshot,
|
||||
bin_node_modules_dir_path: &Path,
|
||||
handler: impl FnMut(&EntrySetupOutcome<'_>),
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), BinEntriesError> {
|
||||
self.set_up_entries_filtered(
|
||||
snapshot,
|
||||
bin_node_modules_dir_path,
|
||||
|
@ -226,7 +269,7 @@ impl<'a> BinEntries<'a> {
|
|||
bin_node_modules_dir_path: &Path,
|
||||
handler: impl FnMut(&EntrySetupOutcome<'_>),
|
||||
only: &HashSet<&NpmPackageId>,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), BinEntriesError> {
|
||||
self.set_up_entries_filtered(
|
||||
snapshot,
|
||||
bin_node_modules_dir_path,
|
||||
|
@ -301,7 +344,7 @@ pub fn set_up_bin_entry<'a>(
|
|||
#[allow(unused_variables)] bin_script: &str,
|
||||
#[allow(unused_variables)] package_path: &'a Path,
|
||||
bin_node_modules_dir_path: &Path,
|
||||
) -> Result<EntrySetupOutcome<'a>, AnyError> {
|
||||
) -> Result<EntrySetupOutcome<'a>, BinEntriesError> {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
set_up_bin_shim(package, bin_name, bin_node_modules_dir_path)?;
|
||||
|
@ -324,14 +367,16 @@ fn set_up_bin_shim(
|
|||
package: &NpmResolutionPackage,
|
||||
bin_name: &str,
|
||||
bin_node_modules_dir_path: &Path,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), BinEntriesError> {
|
||||
use std::fs;
|
||||
let mut cmd_shim = bin_node_modules_dir_path.join(bin_name);
|
||||
|
||||
cmd_shim.set_extension("cmd");
|
||||
let shim = format!("@deno run -A npm:{}/{bin_name} %*", package.id.nv);
|
||||
fs::write(&cmd_shim, shim).with_context(|| {
|
||||
format!("Can't set up '{}' bin at {}", bin_name, cmd_shim.display())
|
||||
fs::write(&cmd_shim, shim).map_err(|err| BinEntriesError::SetUpBin {
|
||||
name: bin_name.to_string(),
|
||||
path: cmd_shim.clone(),
|
||||
source: Box::new(err.into()),
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
|
@ -340,7 +385,7 @@ fn set_up_bin_shim(
|
|||
#[cfg(unix)]
|
||||
/// Make the file at `path` executable if it exists.
|
||||
/// Returns `true` if the file exists, `false` otherwise.
|
||||
fn make_executable_if_exists(path: &Path) -> Result<bool, AnyError> {
|
||||
fn make_executable_if_exists(path: &Path) -> Result<bool, BinEntriesError> {
|
||||
use std::io;
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
let mut perms = match std::fs::metadata(path) {
|
||||
|
@ -355,8 +400,11 @@ fn make_executable_if_exists(path: &Path) -> Result<bool, AnyError> {
|
|||
if perms.mode() & 0o111 == 0 {
|
||||
// if the original file is not executable, make it executable
|
||||
perms.set_mode(perms.mode() | 0o111);
|
||||
std::fs::set_permissions(path, perms).with_context(|| {
|
||||
format!("Setting permissions on '{}'", path.display())
|
||||
std::fs::set_permissions(path, perms).map_err(|source| {
|
||||
BinEntriesError::Permissions {
|
||||
path: path.to_path_buf(),
|
||||
source,
|
||||
}
|
||||
})?;
|
||||
}
|
||||
|
||||
|
@ -395,14 +443,18 @@ fn symlink_bin_entry<'a>(
|
|||
bin_script: &str,
|
||||
package_path: &'a Path,
|
||||
bin_node_modules_dir_path: &Path,
|
||||
) -> Result<EntrySetupOutcome<'a>, AnyError> {
|
||||
) -> Result<EntrySetupOutcome<'a>, BinEntriesError> {
|
||||
use std::io;
|
||||
use std::os::unix::fs::symlink;
|
||||
let link = bin_node_modules_dir_path.join(bin_name);
|
||||
let original = package_path.join(bin_script);
|
||||
|
||||
let found = make_executable_if_exists(&original).with_context(|| {
|
||||
format!("Can't set up '{}' bin at {}", bin_name, original.display())
|
||||
let found = make_executable_if_exists(&original).map_err(|source| {
|
||||
BinEntriesError::SetUpBin {
|
||||
name: bin_name.to_string(),
|
||||
path: original.to_path_buf(),
|
||||
source: Box::new(source),
|
||||
}
|
||||
})?;
|
||||
if !found {
|
||||
return Ok(EntrySetupOutcome::MissingEntrypoint {
|
||||
|
@ -420,27 +472,25 @@ fn symlink_bin_entry<'a>(
|
|||
if let Err(err) = symlink(&original_relative, &link) {
|
||||
if err.kind() == io::ErrorKind::AlreadyExists {
|
||||
// remove and retry
|
||||
std::fs::remove_file(&link).with_context(|| {
|
||||
format!(
|
||||
"Failed to remove existing bin symlink at {}",
|
||||
link.display()
|
||||
)
|
||||
std::fs::remove_file(&link).map_err(|source| {
|
||||
BinEntriesError::RemoveBinSymlink {
|
||||
path: link.clone(),
|
||||
source,
|
||||
}
|
||||
})?;
|
||||
symlink(&original_relative, &link).with_context(|| {
|
||||
format!(
|
||||
"Can't set up '{}' bin at {}",
|
||||
bin_name,
|
||||
original_relative.display()
|
||||
)
|
||||
symlink(&original_relative, &link).map_err(|source| {
|
||||
BinEntriesError::SetUpBin {
|
||||
name: bin_name.to_string(),
|
||||
path: original_relative.to_path_buf(),
|
||||
source: Box::new(source.into()),
|
||||
}
|
||||
})?;
|
||||
return Ok(EntrySetupOutcome::Success);
|
||||
}
|
||||
return Err(err).with_context(|| {
|
||||
format!(
|
||||
"Can't set up '{}' bin at {}",
|
||||
bin_name,
|
||||
original_relative.display()
|
||||
)
|
||||
return Err(BinEntriesError::SetUpBin {
|
||||
name: bin_name.to_string(),
|
||||
path: original_relative.to_path_buf(),
|
||||
source: Box::new(err.into()),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ use std::path::Path;
|
|||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_npm::resolution::NpmResolutionSnapshot;
|
||||
use deno_npm::NpmResolutionPackage;
|
||||
|
@ -29,7 +28,7 @@ pub trait LifecycleScriptsStrategy {
|
|||
fn warn_on_scripts_not_run(
|
||||
&self,
|
||||
packages: &[(&NpmResolutionPackage, PathBuf)],
|
||||
) -> Result<(), AnyError>;
|
||||
) -> Result<(), std::io::Error>;
|
||||
|
||||
fn has_warned(&self, package: &NpmResolutionPackage) -> bool;
|
||||
|
||||
|
@ -38,7 +37,7 @@ pub trait LifecycleScriptsStrategy {
|
|||
fn did_run_scripts(
|
||||
&self,
|
||||
package: &NpmResolutionPackage,
|
||||
) -> Result<(), AnyError>;
|
||||
) -> Result<(), std::io::Error>;
|
||||
}
|
||||
|
||||
pub struct LifecycleScripts<'a> {
|
||||
|
@ -84,6 +83,27 @@ fn is_broken_default_install_script(script: &str, package_path: &Path) -> bool {
|
|||
script == "node-gyp rebuild" && !package_path.join("binding.gyp").exists()
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum LifecycleScriptsError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Io(#[from] std::io::Error),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
BinEntries(#[from] super::bin_entries::BinEntriesError),
|
||||
#[class(inherit)]
|
||||
#[error(
|
||||
"failed to create npm process state tempfile for running lifecycle scripts"
|
||||
)]
|
||||
CreateNpmProcessState(#[source] std::io::Error),
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
Task(AnyError),
|
||||
#[class(generic)]
|
||||
#[error("failed to run scripts for packages: {}", .0.join(", "))]
|
||||
RunScripts(Vec<String>),
|
||||
}
|
||||
|
||||
impl<'a> LifecycleScripts<'a> {
|
||||
pub fn can_run_scripts(&self, package_nv: &PackageNv) -> bool {
|
||||
if !self.strategy.can_run_scripts() {
|
||||
|
@ -141,7 +161,7 @@ impl<'a> LifecycleScripts<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn warn_not_run_scripts(&self) -> Result<(), AnyError> {
|
||||
pub fn warn_not_run_scripts(&self) -> Result<(), std::io::Error> {
|
||||
if !self.packages_with_scripts_not_run.is_empty() {
|
||||
self
|
||||
.strategy
|
||||
|
@ -156,7 +176,7 @@ impl<'a> LifecycleScripts<'a> {
|
|||
packages: &[NpmResolutionPackage],
|
||||
root_node_modules_dir_path: &Path,
|
||||
progress_bar: &ProgressBar,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), LifecycleScriptsError> {
|
||||
let kill_signal = KillSignal::default();
|
||||
let _drop_signal = kill_signal.clone().drop_guard();
|
||||
// we don't run with signals forwarded because once signals
|
||||
|
@ -179,7 +199,7 @@ impl<'a> LifecycleScripts<'a> {
|
|||
root_node_modules_dir_path: &Path,
|
||||
progress_bar: &ProgressBar,
|
||||
kill_signal: KillSignal,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), LifecycleScriptsError> {
|
||||
self.warn_not_run_scripts()?;
|
||||
let get_package_path =
|
||||
|p: &NpmResolutionPackage| self.strategy.package_path(p);
|
||||
|
@ -198,7 +218,7 @@ impl<'a> LifecycleScripts<'a> {
|
|||
snapshot,
|
||||
packages,
|
||||
get_package_path,
|
||||
)?;
|
||||
);
|
||||
let init_cwd = &self.config.initial_cwd;
|
||||
let process_state = crate::npm::managed::npm_process_state(
|
||||
snapshot.as_valid_serialized(),
|
||||
|
@ -222,7 +242,8 @@ impl<'a> LifecycleScripts<'a> {
|
|||
let temp_file_fd =
|
||||
deno_runtime::ops::process::npm_process_state_tempfile(
|
||||
process_state.as_bytes(),
|
||||
).context("failed to create npm process state tempfile for running lifecycle scripts")?;
|
||||
)
|
||||
.map_err(LifecycleScriptsError::CreateNpmProcessState)?;
|
||||
// SAFETY: fd/handle is valid
|
||||
let _temp_file =
|
||||
unsafe { std::fs::File::from_raw_io_handle(temp_file_fd) }; // make sure the file gets closed
|
||||
|
@ -240,7 +261,7 @@ impl<'a> LifecycleScripts<'a> {
|
|||
package,
|
||||
snapshot,
|
||||
get_package_path,
|
||||
)?;
|
||||
);
|
||||
for script_name in ["preinstall", "install", "postinstall"] {
|
||||
if let Some(script) = package.scripts.get(script_name) {
|
||||
if script_name == "install"
|
||||
|
@ -273,7 +294,8 @@ impl<'a> LifecycleScripts<'a> {
|
|||
kill_signal: kill_signal.clone(),
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
.await
|
||||
.map_err(LifecycleScriptsError::Task)?;
|
||||
let stdout = stdout.unwrap();
|
||||
let stderr = stderr.unwrap();
|
||||
if exit_code != 0 {
|
||||
|
@ -322,14 +344,12 @@ impl<'a> LifecycleScripts<'a> {
|
|||
if failed_packages.is_empty() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(AnyError::msg(format!(
|
||||
"failed to run scripts for packages: {}",
|
||||
Err(LifecycleScriptsError::RunScripts(
|
||||
failed_packages
|
||||
.iter()
|
||||
.map(|p| p.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
)))
|
||||
.collect::<Vec<_>>(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -349,7 +369,7 @@ fn resolve_baseline_custom_commands<'a>(
|
|||
snapshot: &'a NpmResolutionSnapshot,
|
||||
packages: &'a [NpmResolutionPackage],
|
||||
get_package_path: impl Fn(&NpmResolutionPackage) -> PathBuf,
|
||||
) -> Result<crate::task_runner::TaskCustomCommands, AnyError> {
|
||||
) -> crate::task_runner::TaskCustomCommands {
|
||||
let mut custom_commands = crate::task_runner::TaskCustomCommands::new();
|
||||
custom_commands
|
||||
.insert("npx".to_string(), Rc::new(crate::task_runner::NpxCommand));
|
||||
|
@ -390,7 +410,7 @@ fn resolve_custom_commands_from_packages<
|
|||
snapshot: &'a NpmResolutionSnapshot,
|
||||
packages: P,
|
||||
get_package_path: impl Fn(&'a NpmResolutionPackage) -> PathBuf,
|
||||
) -> Result<crate::task_runner::TaskCustomCommands, AnyError> {
|
||||
) -> crate::task_runner::TaskCustomCommands {
|
||||
for package in packages {
|
||||
let package_path = get_package_path(package);
|
||||
|
||||
|
@ -409,7 +429,7 @@ fn resolve_custom_commands_from_packages<
|
|||
);
|
||||
}
|
||||
|
||||
Ok(commands)
|
||||
commands
|
||||
}
|
||||
|
||||
// resolves the custom commands from the dependencies of a package
|
||||
|
@ -420,7 +440,7 @@ fn resolve_custom_commands_from_deps(
|
|||
package: &NpmResolutionPackage,
|
||||
snapshot: &NpmResolutionSnapshot,
|
||||
get_package_path: impl Fn(&NpmResolutionPackage) -> PathBuf,
|
||||
) -> Result<crate::task_runner::TaskCustomCommands, AnyError> {
|
||||
) -> crate::task_runner::TaskCustomCommands {
|
||||
let mut bin_entries = BinEntries::new();
|
||||
resolve_custom_commands_from_packages(
|
||||
&mut bin_entries,
|
||||
|
|
|
@ -9,9 +9,9 @@ use std::sync::Arc;
|
|||
|
||||
use async_trait::async_trait;
|
||||
use deno_ast::ModuleSpecifier;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures::stream::FuturesUnordered;
|
||||
use deno_core::futures::StreamExt;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_npm::NpmPackageCacheFolderId;
|
||||
use deno_npm::NpmPackageId;
|
||||
use deno_npm::NpmResolutionPackage;
|
||||
|
@ -134,7 +134,7 @@ impl NpmPackageFsResolver for GlobalNpmPackageResolver {
|
|||
fn resolve_package_cache_folder_id_from_specifier(
|
||||
&self,
|
||||
specifier: &ModuleSpecifier,
|
||||
) -> Result<Option<NpmPackageCacheFolderId>, AnyError> {
|
||||
) -> Result<Option<NpmPackageCacheFolderId>, std::io::Error> {
|
||||
Ok(
|
||||
self
|
||||
.cache
|
||||
|
@ -145,7 +145,7 @@ impl NpmPackageFsResolver for GlobalNpmPackageResolver {
|
|||
async fn cache_packages<'a>(
|
||||
&self,
|
||||
caching: PackageCaching<'a>,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), JsErrorBox> {
|
||||
let package_partitions = match caching {
|
||||
PackageCaching::All => self
|
||||
.resolution
|
||||
|
@ -155,13 +155,16 @@ impl NpmPackageFsResolver for GlobalNpmPackageResolver {
|
|||
.subset(&reqs)
|
||||
.all_system_packages_partitioned(&self.system_info),
|
||||
};
|
||||
cache_packages(&package_partitions.packages, &self.tarball_cache).await?;
|
||||
cache_packages(&package_partitions.packages, &self.tarball_cache)
|
||||
.await
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
|
||||
// create the copy package folders
|
||||
for copy in package_partitions.copy_packages {
|
||||
self
|
||||
.cache
|
||||
.ensure_copy_package(©.get_package_cache_folder_id())?;
|
||||
.ensure_copy_package(©.get_package_cache_folder_id())
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
}
|
||||
|
||||
let mut lifecycle_scripts =
|
||||
|
@ -174,7 +177,9 @@ impl NpmPackageFsResolver for GlobalNpmPackageResolver {
|
|||
lifecycle_scripts.add(package, Cow::Borrowed(&package_folder));
|
||||
}
|
||||
|
||||
lifecycle_scripts.warn_not_run_scripts()?;
|
||||
lifecycle_scripts
|
||||
.warn_not_run_scripts()
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -183,7 +188,7 @@ impl NpmPackageFsResolver for GlobalNpmPackageResolver {
|
|||
async fn cache_packages(
|
||||
packages: &[NpmResolutionPackage],
|
||||
tarball_cache: &Arc<CliNpmTarballCache>,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), deno_npm_cache::EnsurePackageError> {
|
||||
let mut futures_unordered = FuturesUnordered::new();
|
||||
for package in packages {
|
||||
futures_unordered.push(async move {
|
||||
|
@ -235,7 +240,7 @@ impl<'a> super::common::lifecycle_scripts::LifecycleScriptsStrategy
|
|||
fn warn_on_scripts_not_run(
|
||||
&self,
|
||||
packages: &[(&NpmResolutionPackage, PathBuf)],
|
||||
) -> std::result::Result<(), deno_core::anyhow::Error> {
|
||||
) -> std::result::Result<(), std::io::Error> {
|
||||
log::warn!("{} The following packages contained npm lifecycle scripts ({}) that were not executed:", colors::yellow("Warning"), colors::gray("preinstall/install/postinstall"));
|
||||
for (package, _) in packages {
|
||||
log::warn!("┠─ {}", colors::gray(format!("npm:{}", package.id.nv)));
|
||||
|
@ -261,7 +266,7 @@ impl<'a> super::common::lifecycle_scripts::LifecycleScriptsStrategy
|
|||
fn did_run_scripts(
|
||||
&self,
|
||||
_package: &NpmResolutionPackage,
|
||||
) -> std::result::Result<(), deno_core::anyhow::Error> {
|
||||
) -> Result<(), std::io::Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -19,12 +19,11 @@ use std::sync::Arc;
|
|||
use async_trait::async_trait;
|
||||
use deno_ast::ModuleSpecifier;
|
||||
use deno_cache_dir::npm::mixed_case_package_name_decode;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures::stream::FuturesUnordered;
|
||||
use deno_core::futures::StreamExt;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::url::Url;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_npm::resolution::NpmResolutionSnapshot;
|
||||
use deno_npm::NpmPackageCacheFolderId;
|
||||
use deno_npm::NpmPackageId;
|
||||
|
@ -140,7 +139,7 @@ impl LocalNpmPackageResolver {
|
|||
fn resolve_package_folder_from_specifier(
|
||||
&self,
|
||||
specifier: &ModuleSpecifier,
|
||||
) -> Result<Option<PathBuf>, AnyError> {
|
||||
) -> Result<Option<PathBuf>, std::io::Error> {
|
||||
let Some(local_path) = self.resolve_folder_for_specifier(specifier)? else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
@ -225,7 +224,7 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver {
|
|||
fn resolve_package_cache_folder_id_from_specifier(
|
||||
&self,
|
||||
specifier: &ModuleSpecifier,
|
||||
) -> Result<Option<NpmPackageCacheFolderId>, AnyError> {
|
||||
) -> Result<Option<NpmPackageCacheFolderId>, std::io::Error> {
|
||||
let Some(folder_path) =
|
||||
self.resolve_package_folder_from_specifier(specifier)?
|
||||
else {
|
||||
|
@ -251,7 +250,7 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver {
|
|||
async fn cache_packages<'a>(
|
||||
&self,
|
||||
caching: PackageCaching<'a>,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), JsErrorBox> {
|
||||
let snapshot = match caching {
|
||||
PackageCaching::All => self.resolution.snapshot(),
|
||||
PackageCaching::Only(reqs) => self.resolution.subset(&reqs),
|
||||
|
@ -267,6 +266,7 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver {
|
|||
&self.lifecycle_scripts,
|
||||
)
|
||||
.await
|
||||
.map_err(JsErrorBox::from_err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -285,6 +285,38 @@ fn local_node_modules_package_contents_path(
|
|||
.join(&package.id.nv.name)
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum SyncResolutionWithFsError {
|
||||
#[class(inherit)]
|
||||
#[error("Creating '{path}'")]
|
||||
Creating {
|
||||
path: PathBuf,
|
||||
#[source]
|
||||
#[inherit]
|
||||
source: std::io::Error,
|
||||
},
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
CopyDirRecursive(#[from] crate::util::fs::CopyDirRecursiveError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
SymlinkPackageDir(#[from] SymlinkPackageDirError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
BinEntries(#[from] bin_entries::BinEntriesError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
LifecycleScripts(
|
||||
#[from] super::common::lifecycle_scripts::LifecycleScriptsError,
|
||||
),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Io(#[from] std::io::Error),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Other(#[from] JsErrorBox),
|
||||
}
|
||||
|
||||
/// Creates a pnpm style folder structure.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn sync_resolution_with_fs(
|
||||
|
@ -296,7 +328,7 @@ async fn sync_resolution_with_fs(
|
|||
root_node_modules_dir_path: &Path,
|
||||
system_info: &NpmSystemInfo,
|
||||
lifecycle_scripts: &LifecycleScriptsConfig,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), SyncResolutionWithFsError> {
|
||||
if snapshot.is_empty()
|
||||
&& npm_install_deps_provider.workspace_pkgs().is_empty()
|
||||
{
|
||||
|
@ -311,12 +343,18 @@ async fn sync_resolution_with_fs(
|
|||
|
||||
let deno_local_registry_dir = root_node_modules_dir_path.join(".deno");
|
||||
let deno_node_modules_dir = deno_local_registry_dir.join("node_modules");
|
||||
fs::create_dir_all(&deno_node_modules_dir).with_context(|| {
|
||||
format!("Creating '{}'", deno_local_registry_dir.display())
|
||||
fs::create_dir_all(&deno_node_modules_dir).map_err(|source| {
|
||||
SyncResolutionWithFsError::Creating {
|
||||
path: deno_local_registry_dir.to_path_buf(),
|
||||
source,
|
||||
}
|
||||
})?;
|
||||
let bin_node_modules_dir_path = root_node_modules_dir_path.join(".bin");
|
||||
fs::create_dir_all(&bin_node_modules_dir_path).with_context(|| {
|
||||
format!("Creating '{}'", bin_node_modules_dir_path.display())
|
||||
fs::create_dir_all(&bin_node_modules_dir_path).map_err(|source| {
|
||||
SyncResolutionWithFsError::Creating {
|
||||
path: deno_local_registry_dir.to_path_buf(),
|
||||
source,
|
||||
}
|
||||
})?;
|
||||
|
||||
let single_process_lock = LaxSingleProcessFsFlag::lock(
|
||||
|
@ -420,7 +458,8 @@ async fn sync_resolution_with_fs(
|
|||
cache_futures.push(async move {
|
||||
tarball_cache
|
||||
.ensure_package(&package.id.nv, &package.dist)
|
||||
.await?;
|
||||
.await
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
let pb_guard = progress_bar.update_with_prompt(
|
||||
ProgressMessagePrompt::Initialize,
|
||||
&package.id.nv.to_string(),
|
||||
|
@ -441,10 +480,12 @@ async fn sync_resolution_with_fs(
|
|||
// write out a file that indicates this folder has been initialized
|
||||
fs::write(initialized_file, tags)?;
|
||||
|
||||
Ok::<_, AnyError>(())
|
||||
Ok::<_, SyncResolutionWithFsError>(())
|
||||
}
|
||||
})
|
||||
.await??;
|
||||
.await
|
||||
.map_err(JsErrorBox::from_err)?
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
|
||||
if package.bin.is_some() {
|
||||
bin_entries_to_setup.borrow_mut().add(package, package_path);
|
||||
|
@ -458,7 +499,7 @@ async fn sync_resolution_with_fs(
|
|||
|
||||
// finally stop showing the progress bar
|
||||
drop(pb_guard); // explicit for clarity
|
||||
Ok::<_, AnyError>(())
|
||||
Ok::<_, JsErrorBox>(())
|
||||
});
|
||||
} else if matches!(package_state, PackageFolderState::TagsOutdated) {
|
||||
fs::write(initialized_file, tags)?;
|
||||
|
@ -597,8 +638,11 @@ async fn sync_resolution_with_fs(
|
|||
// symlink the dep into the package's child node_modules folder
|
||||
let dest_node_modules = remote.base_dir.join("node_modules");
|
||||
if !existing_child_node_modules_dirs.contains(&dest_node_modules) {
|
||||
fs::create_dir_all(&dest_node_modules).with_context(|| {
|
||||
format!("Creating '{}'", dest_node_modules.display())
|
||||
fs::create_dir_all(&dest_node_modules).map_err(|source| {
|
||||
SyncResolutionWithFsError::Creating {
|
||||
path: dest_node_modules.clone(),
|
||||
source,
|
||||
}
|
||||
})?;
|
||||
existing_child_node_modules_dirs.insert(dest_node_modules.clone());
|
||||
}
|
||||
|
@ -813,7 +857,7 @@ impl<'a> super::common::lifecycle_scripts::LifecycleScriptsStrategy
|
|||
fn did_run_scripts(
|
||||
&self,
|
||||
package: &NpmResolutionPackage,
|
||||
) -> std::result::Result<(), deno_core::anyhow::Error> {
|
||||
) -> std::result::Result<(), std::io::Error> {
|
||||
std::fs::write(self.ran_scripts_file(package), "")?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -821,7 +865,7 @@ impl<'a> super::common::lifecycle_scripts::LifecycleScriptsStrategy
|
|||
fn warn_on_scripts_not_run(
|
||||
&self,
|
||||
packages: &[(&NpmResolutionPackage, std::path::PathBuf)],
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), std::io::Error> {
|
||||
if !packages.is_empty() {
|
||||
log::warn!("{} The following packages contained npm lifecycle scripts ({}) that were not executed:", colors::yellow("Warning"), colors::gray("preinstall/install/postinstall"));
|
||||
|
||||
|
@ -1041,15 +1085,42 @@ fn get_package_folder_id_from_folder_name(
|
|||
})
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum SymlinkPackageDirError {
|
||||
#[class(inherit)]
|
||||
#[error("Creating '{parent}'")]
|
||||
Creating {
|
||||
parent: PathBuf,
|
||||
#[source]
|
||||
#[inherit]
|
||||
source: std::io::Error,
|
||||
},
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Other(#[from] std::io::Error),
|
||||
#[cfg(windows)]
|
||||
#[class(inherit)]
|
||||
#[error("Creating junction in node_modules folder")]
|
||||
FailedCreatingJunction {
|
||||
#[source]
|
||||
#[inherit]
|
||||
source: std::io::Error,
|
||||
},
|
||||
}
|
||||
|
||||
fn symlink_package_dir(
|
||||
old_path: &Path,
|
||||
new_path: &Path,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), SymlinkPackageDirError> {
|
||||
let new_parent = new_path.parent().unwrap();
|
||||
if new_parent.file_name().unwrap() != "node_modules" {
|
||||
// create the parent folder that will contain the symlink
|
||||
fs::create_dir_all(new_parent)
|
||||
.with_context(|| format!("Creating '{}'", new_parent.display()))?;
|
||||
fs::create_dir_all(new_parent).map_err(|source| {
|
||||
SymlinkPackageDirError::Creating {
|
||||
parent: new_parent.to_path_buf(),
|
||||
source,
|
||||
}
|
||||
})?;
|
||||
}
|
||||
|
||||
// need to delete the previous symlink before creating a new one
|
||||
|
@ -1075,7 +1146,7 @@ fn junction_or_symlink_dir(
|
|||
old_path_relative: &Path,
|
||||
old_path: &Path,
|
||||
new_path: &Path,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), SymlinkPackageDirError> {
|
||||
static USE_JUNCTIONS: std::sync::atomic::AtomicBool =
|
||||
std::sync::atomic::AtomicBool::new(false);
|
||||
|
||||
|
@ -1084,8 +1155,9 @@ fn junction_or_symlink_dir(
|
|||
// needing to elevate privileges on Windows.
|
||||
// Note: junctions don't support relative paths, so we need to use the
|
||||
// absolute path here.
|
||||
return junction::create(old_path, new_path)
|
||||
.context("Failed creating junction in node_modules folder");
|
||||
return junction::create(old_path, new_path).map_err(|source| {
|
||||
SymlinkPackageDirError::FailedCreatingJunction { source }
|
||||
});
|
||||
}
|
||||
|
||||
match symlink_dir(&crate::sys::CliSys::default(), old_path_relative, new_path)
|
||||
|
@ -1095,8 +1167,9 @@ fn junction_or_symlink_dir(
|
|||
if symlink_err.kind() == std::io::ErrorKind::PermissionDenied =>
|
||||
{
|
||||
USE_JUNCTIONS.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||
junction::create(old_path, new_path)
|
||||
.context("Failed creating junction in node_modules folder")
|
||||
junction::create(old_path, new_path).map_err(|source| {
|
||||
SymlinkPackageDirError::FailedCreatingJunction { source }
|
||||
})
|
||||
}
|
||||
Err(symlink_err) => {
|
||||
log::warn!(
|
||||
|
@ -1104,8 +1177,9 @@ fn junction_or_symlink_dir(
|
|||
colors::yellow("Warning")
|
||||
);
|
||||
USE_JUNCTIONS.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||
junction::create(old_path, new_path)
|
||||
.context("Failed creating junction in node_modules folder")
|
||||
junction::create(old_path, new_path).map_err(|source| {
|
||||
SymlinkPackageDirError::FailedCreatingJunction { source }
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ use std::sync::Arc;
|
|||
use deno_npm::NpmSystemInfo;
|
||||
|
||||
pub use self::common::NpmPackageFsResolver;
|
||||
pub use self::common::NpmPackageFsResolverPackageFolderError;
|
||||
use self::global::GlobalNpmPackageResolver;
|
||||
use self::local::LocalNpmPackageResolver;
|
||||
use super::resolution::NpmResolution;
|
||||
|
|
|
@ -33,6 +33,7 @@ pub use self::managed::CliManagedNpmResolverCreateOptions;
|
|||
pub use self::managed::CliNpmResolverManagedSnapshotOption;
|
||||
pub use self::managed::ManagedCliNpmResolver;
|
||||
pub use self::managed::PackageCaching;
|
||||
pub use self::managed::ResolvePkgFolderFromDenoModuleError;
|
||||
pub use self::permission_checker::NpmRegistryReadPermissionChecker;
|
||||
pub use self::permission_checker::NpmRegistryReadPermissionCheckerMode;
|
||||
use crate::file_fetcher::CliFileFetcher;
|
||||
|
@ -90,7 +91,9 @@ impl deno_npm_cache::NpmCacheHttpClient for CliNpmCacheHttpClient {
|
|||
| Json { .. }
|
||||
| ToStr { .. }
|
||||
| RedirectHeaderParse { .. }
|
||||
| TooManyRedirects => None,
|
||||
| TooManyRedirects
|
||||
| NotFound
|
||||
| Other(_) => None,
|
||||
BadResponse(bad_response_error) => {
|
||||
Some(bad_response_error.status_code)
|
||||
}
|
||||
|
|
|
@ -6,9 +6,8 @@ use std::io::ErrorKind;
|
|||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_runtime::deno_node::NodePermissions;
|
||||
use sys_traits::FsCanonicalize;
|
||||
|
||||
|
@ -28,6 +27,16 @@ pub struct NpmRegistryReadPermissionChecker {
|
|||
mode: NpmRegistryReadPermissionCheckerMode,
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
#[class(inherit)]
|
||||
#[error("failed canonicalizing '{path}'")]
|
||||
struct EnsureRegistryReadPermissionError {
|
||||
path: PathBuf,
|
||||
#[source]
|
||||
#[inherit]
|
||||
source: std::io::Error,
|
||||
}
|
||||
|
||||
impl NpmRegistryReadPermissionChecker {
|
||||
pub fn new(sys: CliSys, mode: NpmRegistryReadPermissionCheckerMode) -> Self {
|
||||
Self {
|
||||
|
@ -42,7 +51,7 @@ impl NpmRegistryReadPermissionChecker {
|
|||
&self,
|
||||
permissions: &mut dyn NodePermissions,
|
||||
path: &'a Path,
|
||||
) -> Result<Cow<'a, Path>, AnyError> {
|
||||
) -> Result<Cow<'a, Path>, JsErrorBox> {
|
||||
if permissions.query_read_all() {
|
||||
return Ok(Cow::Borrowed(path)); // skip permissions checks below
|
||||
}
|
||||
|
@ -52,7 +61,9 @@ impl NpmRegistryReadPermissionChecker {
|
|||
if path.components().any(|c| c.as_os_str() == "node_modules") {
|
||||
Ok(Cow::Borrowed(path))
|
||||
} else {
|
||||
permissions.check_read_path(path).map_err(Into::into)
|
||||
permissions
|
||||
.check_read_path(path)
|
||||
.map_err(JsErrorBox::from_err)
|
||||
}
|
||||
}
|
||||
NpmRegistryReadPermissionCheckerMode::Global(registry_path)
|
||||
|
@ -66,7 +77,7 @@ impl NpmRegistryReadPermissionChecker {
|
|||
if is_path_in_node_modules {
|
||||
let mut cache = self.cache.lock();
|
||||
let mut canonicalize =
|
||||
|path: &Path| -> Result<Option<PathBuf>, AnyError> {
|
||||
|path: &Path| -> Result<Option<PathBuf>, JsErrorBox> {
|
||||
match cache.get(path) {
|
||||
Some(canon) => Ok(Some(canon.clone())),
|
||||
None => match self.sys.fs_canonicalize(path) {
|
||||
|
@ -78,9 +89,12 @@ impl NpmRegistryReadPermissionChecker {
|
|||
if e.kind() == ErrorKind::NotFound {
|
||||
return Ok(None);
|
||||
}
|
||||
Err(AnyError::from(e)).with_context(|| {
|
||||
format!("failed canonicalizing '{}'", path.display())
|
||||
})
|
||||
Err(JsErrorBox::from_err(
|
||||
EnsureRegistryReadPermissionError {
|
||||
path: path.to_path_buf(),
|
||||
source: e,
|
||||
},
|
||||
))
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -98,7 +112,9 @@ impl NpmRegistryReadPermissionChecker {
|
|||
}
|
||||
}
|
||||
|
||||
permissions.check_read_path(path).map_err(Into::into)
|
||||
permissions
|
||||
.check_read_path(path)
|
||||
.map_err(JsErrorBox::from_err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,13 +3,11 @@
|
|||
use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op2;
|
||||
use deno_core::v8;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::OpState;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_runtime::deno_permissions::ChildPermissionsArg;
|
||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||
use deno_runtime::deno_web::StartTime;
|
||||
|
@ -78,7 +76,7 @@ pub fn op_pledge_test_permissions(
|
|||
pub fn op_restore_test_permissions(
|
||||
state: &mut OpState,
|
||||
#[serde] token: Uuid,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), JsErrorBox> {
|
||||
if let Some(permissions_holder) = state.try_take::<PermissionsHolder>() {
|
||||
if token != permissions_holder.0 {
|
||||
panic!("restore test permissions token does not match the stored token");
|
||||
|
@ -88,7 +86,7 @@ pub fn op_restore_test_permissions(
|
|||
state.put::<PermissionsContainer>(permissions);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(generic_error("no permissions to restore"))
|
||||
Err(JsErrorBox::generic("no permissions to restore"))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,9 +104,9 @@ fn op_register_bench(
|
|||
only: bool,
|
||||
warmup: bool,
|
||||
#[buffer] ret_buf: &mut [u8],
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), JsErrorBox> {
|
||||
if ret_buf.len() != 4 {
|
||||
return Err(type_error(format!(
|
||||
return Err(JsErrorBox::type_error(format!(
|
||||
"Invalid ret_buf length: {}",
|
||||
ret_buf.len()
|
||||
)));
|
||||
|
|
|
@ -94,10 +94,12 @@ pub fn op_jupyter_input(
|
|||
None
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum JupyterBroadcastError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
SerdeJson(serde_json::Error),
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
ZeroMq(AnyError),
|
||||
}
|
||||
|
|
|
@ -2,25 +2,36 @@
|
|||
|
||||
use deno_ast::MediaType;
|
||||
use deno_ast::ModuleSpecifier;
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_ast::ParseDiagnostic;
|
||||
use deno_core::op2;
|
||||
|
||||
use crate::tools::lint;
|
||||
|
||||
deno_core::extension!(deno_lint, ops = [op_lint_create_serialized_ast,],);
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum LintError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Io(#[from] std::io::Error),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
ParseDiagnostic(#[from] ParseDiagnostic),
|
||||
#[class(type)]
|
||||
#[error("Failed to parse path as URL: {0}")]
|
||||
PathParse(std::path::PathBuf),
|
||||
}
|
||||
|
||||
#[op2]
|
||||
#[buffer]
|
||||
fn op_lint_create_serialized_ast(
|
||||
#[string] file_name: &str,
|
||||
#[string] source: String,
|
||||
) -> Result<Vec<u8>, AnyError> {
|
||||
) -> Result<Vec<u8>, LintError> {
|
||||
let file_text = deno_ast::strip_bom(source);
|
||||
let path = std::env::current_dir()?.join(file_name);
|
||||
let specifier = ModuleSpecifier::from_file_path(&path).map_err(|_| {
|
||||
generic_error(format!("Failed to parse path as URL: {}", path.display()))
|
||||
})?;
|
||||
let specifier = ModuleSpecifier::from_file_path(&path)
|
||||
.map_err(|_| LintError::PathParse(path))?;
|
||||
let media_type = MediaType::from_specifier(&specifier);
|
||||
let parsed_source = deno_ast::parse_program(deno_ast::ParseParams {
|
||||
specifier,
|
||||
|
|
|
@ -3,13 +3,11 @@
|
|||
use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op2;
|
||||
use deno_core::v8;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::OpState;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_runtime::deno_permissions::ChildPermissionsArg;
|
||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||
use uuid::Uuid;
|
||||
|
@ -73,7 +71,7 @@ pub fn op_pledge_test_permissions(
|
|||
pub fn op_restore_test_permissions(
|
||||
state: &mut OpState,
|
||||
#[serde] token: Uuid,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), JsErrorBox> {
|
||||
if let Some(permissions_holder) = state.try_take::<PermissionsHolder>() {
|
||||
if token != permissions_holder.0 {
|
||||
panic!("restore test permissions token does not match the stored token");
|
||||
|
@ -83,7 +81,7 @@ pub fn op_restore_test_permissions(
|
|||
state.put::<PermissionsContainer>(permissions);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(generic_error("no permissions to restore"))
|
||||
Err(JsErrorBox::generic("no permissions to restore"))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,9 +101,9 @@ fn op_register_test(
|
|||
#[smi] line_number: u32,
|
||||
#[smi] column_number: u32,
|
||||
#[buffer] ret_buf: &mut [u8],
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), JsErrorBox> {
|
||||
if ret_buf.len() != 4 {
|
||||
return Err(type_error(format!(
|
||||
return Err(JsErrorBox::type_error(format!(
|
||||
"Invalid ret_buf length: {}",
|
||||
ret_buf.len()
|
||||
)));
|
||||
|
|
|
@ -11,12 +11,12 @@ use dashmap::DashSet;
|
|||
use deno_ast::MediaType;
|
||||
use deno_config::workspace::MappedResolutionDiagnostic;
|
||||
use deno_config::workspace::MappedResolutionError;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::ModuleSourceCode;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_graph::source::ResolveError;
|
||||
use deno_graph::source::UnknownBuiltInNodeModuleError;
|
||||
use deno_graph::NpmLoadError;
|
||||
|
@ -61,7 +61,8 @@ pub struct ModuleCodeStringSource {
|
|||
pub media_type: MediaType,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
#[derive(Debug, Error, deno_error::JsError)]
|
||||
#[class(type)]
|
||||
#[error("{media_type} files are not supported in npm packages: {specifier}")]
|
||||
pub struct NotSupportedKindInNpmError {
|
||||
pub media_type: MediaType,
|
||||
|
@ -225,10 +226,12 @@ impl CliResolver {
|
|||
) => match mapped_resolution_error {
|
||||
MappedResolutionError::Specifier(e) => ResolveError::Specifier(e),
|
||||
// deno_graph checks specifically for an ImportMapError
|
||||
MappedResolutionError::ImportMap(e) => ResolveError::Other(e.into()),
|
||||
err => ResolveError::Other(err.into()),
|
||||
MappedResolutionError::ImportMap(e) => ResolveError::ImportMap(e),
|
||||
MappedResolutionError::Workspace(e) => {
|
||||
ResolveError::Other(JsErrorBox::from_err(e))
|
||||
}
|
||||
},
|
||||
err => ResolveError::Other(err.into()),
|
||||
err => ResolveError::Other(JsErrorBox::from_err(err)),
|
||||
})?;
|
||||
|
||||
if resolution.found_package_json_dep {
|
||||
|
@ -356,26 +359,28 @@ impl<'a> deno_graph::source::NpmResolver for WorkerCliNpmGraphResolver<'a> {
|
|||
.map(|r| {
|
||||
r.map_err(|err| match err {
|
||||
NpmResolutionError::Registry(e) => {
|
||||
NpmLoadError::RegistryInfo(Arc::new(e.into()))
|
||||
NpmLoadError::RegistryInfo(Arc::new(e))
|
||||
}
|
||||
NpmResolutionError::Resolution(e) => {
|
||||
NpmLoadError::PackageReqResolution(Arc::new(e.into()))
|
||||
NpmLoadError::PackageReqResolution(Arc::new(e))
|
||||
}
|
||||
NpmResolutionError::DependencyEntry(e) => {
|
||||
NpmLoadError::PackageReqResolution(Arc::new(e.into()))
|
||||
NpmLoadError::PackageReqResolution(Arc::new(e))
|
||||
}
|
||||
})
|
||||
})
|
||||
.collect(),
|
||||
dep_graph_result: match top_level_result {
|
||||
Ok(()) => result.dependencies_result.map_err(Arc::new),
|
||||
Ok(()) => result
|
||||
.dependencies_result
|
||||
.map_err(|e| Arc::new(e) as Arc<dyn deno_error::JsErrorClass>),
|
||||
Err(err) => Err(Arc::new(err)),
|
||||
},
|
||||
}
|
||||
}
|
||||
None => {
|
||||
let err = Arc::new(anyhow!(
|
||||
"npm specifiers were requested; but --no-npm is specified"
|
||||
let err = Arc::new(JsErrorBox::generic(
|
||||
"npm specifiers were requested; but --no-npm is specified",
|
||||
));
|
||||
NpmResolvePkgReqsResult {
|
||||
results: package_reqs
|
||||
|
|
|
@ -21,9 +21,8 @@ use deno_config::workspace::MappedResolutionError;
|
|||
use deno_config::workspace::ResolverWorkspaceJsrPackage;
|
||||
use deno_config::workspace::WorkspaceResolver;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::error::ModuleLoaderError;
|
||||
use deno_core::futures::future::LocalBoxFuture;
|
||||
use deno_core::futures::FutureExt;
|
||||
use deno_core::v8_set_flags;
|
||||
|
@ -36,6 +35,7 @@ use deno_core::ModuleType;
|
|||
use deno_core::RequestedModuleType;
|
||||
use deno_core::ResolutionKind;
|
||||
use deno_core::SourceCodeCacheInfo;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_npm::npm_rc::ResolvedNpmRc;
|
||||
use deno_package_json::PackageJsonDepValue;
|
||||
use deno_resolver::cjs::IsCjsResolutionMode;
|
||||
|
@ -182,25 +182,32 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
|||
raw_specifier: &str,
|
||||
referrer: &str,
|
||||
kind: ResolutionKind,
|
||||
) -> Result<ModuleSpecifier, AnyError> {
|
||||
) -> Result<ModuleSpecifier, ModuleLoaderError> {
|
||||
let referrer = if referrer == "." {
|
||||
if kind != ResolutionKind::MainModule {
|
||||
return Err(generic_error(format!(
|
||||
"Expected to resolve main module, got {:?} instead.",
|
||||
kind
|
||||
)));
|
||||
return Err(
|
||||
JsErrorBox::generic(format!(
|
||||
"Expected to resolve main module, got {:?} instead.",
|
||||
kind
|
||||
))
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
let current_dir = std::env::current_dir().unwrap();
|
||||
deno_core::resolve_path(".", ¤t_dir)?
|
||||
} else {
|
||||
ModuleSpecifier::parse(referrer).map_err(|err| {
|
||||
type_error(format!("Referrer uses invalid specifier: {}", err))
|
||||
JsErrorBox::type_error(format!(
|
||||
"Referrer uses invalid specifier: {}",
|
||||
err
|
||||
))
|
||||
})?
|
||||
};
|
||||
let referrer_kind = if self
|
||||
.shared
|
||||
.cjs_tracker
|
||||
.is_maybe_cjs(&referrer, MediaType::from_specifier(&referrer))?
|
||||
.is_maybe_cjs(&referrer, MediaType::from_specifier(&referrer))
|
||||
.map_err(JsErrorBox::from_err)?
|
||||
{
|
||||
ResolutionMode::Require
|
||||
} else {
|
||||
|
@ -217,7 +224,8 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
|||
&referrer,
|
||||
referrer_kind,
|
||||
NodeResolutionKind::Execution,
|
||||
)?
|
||||
)
|
||||
.map_err(JsErrorBox::from_err)?
|
||||
.into_url(),
|
||||
);
|
||||
}
|
||||
|
@ -245,14 +253,18 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
|||
Some(&referrer),
|
||||
referrer_kind,
|
||||
NodeResolutionKind::Execution,
|
||||
)?,
|
||||
)
|
||||
.map_err(JsErrorBox::from_err)?,
|
||||
),
|
||||
Ok(MappedResolution::PackageJson {
|
||||
dep_result,
|
||||
sub_path,
|
||||
alias,
|
||||
..
|
||||
}) => match dep_result.as_ref().map_err(|e| AnyError::from(e.clone()))? {
|
||||
}) => match dep_result
|
||||
.as_ref()
|
||||
.map_err(|e| JsErrorBox::from_err(e.clone()))?
|
||||
{
|
||||
PackageJsonDepValue::Req(req) => self
|
||||
.shared
|
||||
.npm_req_resolver
|
||||
|
@ -263,7 +275,7 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
|||
referrer_kind,
|
||||
NodeResolutionKind::Execution,
|
||||
)
|
||||
.map_err(AnyError::from),
|
||||
.map_err(|e| JsErrorBox::from_err(e).into()),
|
||||
PackageJsonDepValue::Workspace(version_req) => {
|
||||
let pkg_folder = self
|
||||
.shared
|
||||
|
@ -271,7 +283,8 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
|||
.resolve_workspace_pkg_json_folder_for_pkg_json_dep(
|
||||
alias,
|
||||
version_req,
|
||||
)?;
|
||||
)
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
Ok(
|
||||
self
|
||||
.shared
|
||||
|
@ -282,7 +295,8 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
|||
Some(&referrer),
|
||||
referrer_kind,
|
||||
NodeResolutionKind::Execution,
|
||||
)?,
|
||||
)
|
||||
.map_err(JsErrorBox::from_err)?,
|
||||
)
|
||||
}
|
||||
},
|
||||
|
@ -291,12 +305,18 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
|||
if let Ok(reference) =
|
||||
NpmPackageReqReference::from_specifier(&specifier)
|
||||
{
|
||||
return Ok(self.shared.npm_req_resolver.resolve_req_reference(
|
||||
&reference,
|
||||
&referrer,
|
||||
referrer_kind,
|
||||
NodeResolutionKind::Execution,
|
||||
)?);
|
||||
return Ok(
|
||||
self
|
||||
.shared
|
||||
.npm_req_resolver
|
||||
.resolve_req_reference(
|
||||
&reference,
|
||||
&referrer,
|
||||
referrer_kind,
|
||||
NodeResolutionKind::Execution,
|
||||
)
|
||||
.map_err(JsErrorBox::from_err)?,
|
||||
);
|
||||
}
|
||||
|
||||
if specifier.scheme() == "jsr" {
|
||||
|
@ -318,18 +338,22 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
|||
Err(err)
|
||||
if err.is_unmapped_bare_specifier() && referrer.scheme() == "file" =>
|
||||
{
|
||||
let maybe_res = self.shared.npm_req_resolver.resolve_if_for_npm_pkg(
|
||||
raw_specifier,
|
||||
&referrer,
|
||||
referrer_kind,
|
||||
NodeResolutionKind::Execution,
|
||||
)?;
|
||||
let maybe_res = self
|
||||
.shared
|
||||
.npm_req_resolver
|
||||
.resolve_if_for_npm_pkg(
|
||||
raw_specifier,
|
||||
&referrer,
|
||||
referrer_kind,
|
||||
NodeResolutionKind::Execution,
|
||||
)
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
if let Some(res) = maybe_res {
|
||||
return Ok(res.into_url());
|
||||
}
|
||||
Err(err.into())
|
||||
Err(JsErrorBox::from_err(err).into())
|
||||
}
|
||||
Err(err) => Err(err.into()),
|
||||
Err(err) => Err(JsErrorBox::from_err(err).into()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -360,9 +384,9 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
|||
{
|
||||
Ok(response) => response,
|
||||
Err(err) => {
|
||||
return deno_core::ModuleLoadResponse::Sync(Err(type_error(
|
||||
format!("{:#}", err),
|
||||
)));
|
||||
return deno_core::ModuleLoadResponse::Sync(Err(
|
||||
JsErrorBox::type_error(format!("{:#}", err)).into(),
|
||||
));
|
||||
}
|
||||
};
|
||||
return deno_core::ModuleLoadResponse::Sync(Ok(
|
||||
|
@ -420,9 +444,9 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
|||
{
|
||||
Ok(is_maybe_cjs) => is_maybe_cjs,
|
||||
Err(err) => {
|
||||
return deno_core::ModuleLoadResponse::Sync(Err(type_error(
|
||||
format!("{:?}", err),
|
||||
)));
|
||||
return deno_core::ModuleLoadResponse::Sync(Err(
|
||||
JsErrorBox::type_error(format!("{:?}", err)).into(),
|
||||
));
|
||||
}
|
||||
};
|
||||
if is_maybe_cjs {
|
||||
|
@ -482,12 +506,16 @@ impl ModuleLoader for EmbeddedModuleLoader {
|
|||
))
|
||||
}
|
||||
}
|
||||
Ok(None) => deno_core::ModuleLoadResponse::Sync(Err(type_error(
|
||||
format!("{MODULE_NOT_FOUND}: {}", original_specifier),
|
||||
))),
|
||||
Err(err) => deno_core::ModuleLoadResponse::Sync(Err(type_error(
|
||||
format!("{:?}", err),
|
||||
))),
|
||||
Ok(None) => deno_core::ModuleLoadResponse::Sync(Err(
|
||||
JsErrorBox::type_error(format!(
|
||||
"{MODULE_NOT_FOUND}: {}",
|
||||
original_specifier
|
||||
))
|
||||
.into(),
|
||||
)),
|
||||
Err(err) => deno_core::ModuleLoadResponse::Sync(Err(
|
||||
JsErrorBox::type_error(format!("{:?}", err)).into(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -553,7 +581,7 @@ impl NodeRequireLoader for EmbeddedModuleLoader {
|
|||
&self,
|
||||
permissions: &mut dyn deno_runtime::deno_node::NodePermissions,
|
||||
path: &'a std::path::Path,
|
||||
) -> Result<Cow<'a, std::path::Path>, AnyError> {
|
||||
) -> Result<Cow<'a, std::path::Path>, JsErrorBox> {
|
||||
if self.shared.modules.has_file(path) {
|
||||
// allow reading if the file is in the snapshot
|
||||
return Ok(Cow::Borrowed(path));
|
||||
|
@ -563,17 +591,23 @@ impl NodeRequireLoader for EmbeddedModuleLoader {
|
|||
.shared
|
||||
.npm_registry_permission_checker
|
||||
.ensure_read_permission(permissions, path)
|
||||
.map_err(JsErrorBox::from_err)
|
||||
}
|
||||
|
||||
fn load_text_file_lossy(
|
||||
&self,
|
||||
path: &std::path::Path,
|
||||
) -> Result<Cow<'static, str>, AnyError> {
|
||||
let file_entry = self.shared.vfs.file_entry(path)?;
|
||||
) -> Result<Cow<'static, str>, JsErrorBox> {
|
||||
let file_entry = self
|
||||
.shared
|
||||
.vfs
|
||||
.file_entry(path)
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
let file_bytes = self
|
||||
.shared
|
||||
.vfs
|
||||
.read_file_all(file_entry, VfsFileSubDataKind::ModuleGraph)?;
|
||||
.read_file_all(file_entry, VfsFileSubDataKind::ModuleGraph)
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
Ok(from_utf8_lossy_cow(file_bytes))
|
||||
}
|
||||
|
||||
|
@ -626,10 +660,10 @@ struct StandaloneRootCertStoreProvider {
|
|||
}
|
||||
|
||||
impl RootCertStoreProvider for StandaloneRootCertStoreProvider {
|
||||
fn get_or_try_init(&self) -> Result<&RootCertStore, AnyError> {
|
||||
fn get_or_try_init(&self) -> Result<&RootCertStore, JsErrorBox> {
|
||||
self.cell.get_or_try_init(|| {
|
||||
get_root_cert_store(None, self.ca_stores.clone(), self.ca_data.clone())
|
||||
.map_err(|err| err.into())
|
||||
.map_err(JsErrorBox::from_err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,9 @@ use std::sync::Arc;
|
|||
use std::time::Duration;
|
||||
|
||||
use deno_config::glob::WalkEntry;
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::error::CoreError;
|
||||
use deno_core::error::JsError;
|
||||
use deno_core::futures::future;
|
||||
use deno_core::futures::stream;
|
||||
|
@ -18,6 +19,7 @@ use deno_core::unsync::spawn_blocking;
|
|||
use deno_core::v8;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::PollEventLoopOptions;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_runtime::deno_permissions::Permissions;
|
||||
use deno_runtime::deno_permissions::PermissionsContainer;
|
||||
use deno_runtime::permissions::RuntimePermissionDescriptorParser;
|
||||
|
@ -162,17 +164,14 @@ async fn bench_specifier(
|
|||
.await
|
||||
{
|
||||
Ok(()) => Ok(()),
|
||||
Err(error) => {
|
||||
if error.is::<JsError>() {
|
||||
sender.send(BenchEvent::UncaughtError(
|
||||
specifier.to_string(),
|
||||
Box::new(error.downcast::<JsError>().unwrap()),
|
||||
))?;
|
||||
Ok(())
|
||||
} else {
|
||||
Err(error)
|
||||
}
|
||||
Err(CoreError::Js(error)) => {
|
||||
sender.send(BenchEvent::UncaughtError(
|
||||
specifier.to_string(),
|
||||
Box::new(error),
|
||||
))?;
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => Err(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,7 +182,7 @@ async fn bench_specifier_inner(
|
|||
specifier: ModuleSpecifier,
|
||||
sender: &UnboundedSender<BenchEvent>,
|
||||
filter: TestFilter,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), CoreError> {
|
||||
let mut worker = worker_factory
|
||||
.create_custom_worker(
|
||||
WorkerExecutionMode::Bench,
|
||||
|
@ -230,14 +229,18 @@ async fn bench_specifier_inner(
|
|||
.partial_cmp(&groups.get_index_of(&d2.group).unwrap())
|
||||
.unwrap()
|
||||
});
|
||||
sender.send(BenchEvent::Plan(BenchPlan {
|
||||
origin: specifier.to_string(),
|
||||
total: benchmarks.len(),
|
||||
used_only,
|
||||
names: benchmarks.iter().map(|(d, _)| d.name.clone()).collect(),
|
||||
}))?;
|
||||
sender
|
||||
.send(BenchEvent::Plan(BenchPlan {
|
||||
origin: specifier.to_string(),
|
||||
total: benchmarks.len(),
|
||||
used_only,
|
||||
names: benchmarks.iter().map(|(d, _)| d.name.clone()).collect(),
|
||||
}))
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
for (desc, function) in benchmarks {
|
||||
sender.send(BenchEvent::Wait(desc.id))?;
|
||||
sender
|
||||
.send(BenchEvent::Wait(desc.id))
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
let call = worker.js_runtime.call(&function);
|
||||
let result = worker
|
||||
.js_runtime
|
||||
|
@ -245,8 +248,11 @@ async fn bench_specifier_inner(
|
|||
.await?;
|
||||
let scope = &mut worker.js_runtime.handle_scope();
|
||||
let result = v8::Local::new(scope, result);
|
||||
let result = serde_v8::from_v8::<BenchResult>(scope, result)?;
|
||||
sender.send(BenchEvent::Result(desc.id, result))?;
|
||||
let result = serde_v8::from_v8::<BenchResult>(scope, result)
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
sender
|
||||
.send(BenchEvent::Result(desc.id, result))
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
}
|
||||
|
||||
// Ignore `defaultPrevented` of the `beforeunload` event. We don't allow the
|
||||
|
@ -356,13 +362,13 @@ async fn bench_specifiers(
|
|||
reporter.report_end(&report);
|
||||
|
||||
if used_only {
|
||||
return Err(generic_error(
|
||||
return Err(anyhow!(
|
||||
"Bench failed because the \"only\" option was used",
|
||||
));
|
||||
}
|
||||
|
||||
if report.failed > 0 {
|
||||
return Err(generic_error("Bench failed"));
|
||||
return Err(anyhow!("Bench failed"));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -440,7 +446,7 @@ pub async fn run_benchmarks(
|
|||
.collect::<Vec<_>>();
|
||||
|
||||
if specifiers.is_empty() {
|
||||
return Err(generic_error("No bench modules found"));
|
||||
return Err(anyhow!("No bench modules found"));
|
||||
}
|
||||
|
||||
let main_graph_container = factory.main_module_graph_container().await?;
|
||||
|
|
|
@ -6,7 +6,9 @@ use std::sync::Arc;
|
|||
|
||||
use deno_ast::MediaType;
|
||||
use deno_ast::ModuleSpecifier;
|
||||
use deno_config::deno_json;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_graph::Module;
|
||||
use deno_graph::ModuleError;
|
||||
use deno_graph::ModuleGraph;
|
||||
|
@ -112,6 +114,27 @@ pub struct TypeChecker {
|
|||
sys: CliSys,
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum CheckError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Diagnostics(#[from] Diagnostics),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
ConfigFile(#[from] deno_json::ConfigFileError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
ToMaybeJsxImportSourceConfig(
|
||||
#[from] deno_json::ToMaybeJsxImportSourceConfigError,
|
||||
),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
TscExec(#[from] tsc::ExecError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Other(#[from] JsErrorBox),
|
||||
}
|
||||
|
||||
impl TypeChecker {
|
||||
pub fn new(
|
||||
caches: Arc<Caches>,
|
||||
|
@ -141,7 +164,7 @@ impl TypeChecker {
|
|||
&self,
|
||||
graph: ModuleGraph,
|
||||
options: CheckOptions,
|
||||
) -> Result<Arc<ModuleGraph>, AnyError> {
|
||||
) -> Result<Arc<ModuleGraph>, CheckError> {
|
||||
let (graph, mut diagnostics) =
|
||||
self.check_diagnostics(graph, options).await?;
|
||||
diagnostics.emit_warnings();
|
||||
|
@ -160,7 +183,7 @@ impl TypeChecker {
|
|||
&self,
|
||||
mut graph: ModuleGraph,
|
||||
options: CheckOptions,
|
||||
) -> Result<(Arc<ModuleGraph>, Diagnostics), AnyError> {
|
||||
) -> Result<(Arc<ModuleGraph>, Diagnostics), CheckError> {
|
||||
if !options.type_check_mode.is_true() || graph.roots.is_empty() {
|
||||
return Ok((graph.into(), Default::default()));
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@ use std::sync::Arc;
|
|||
|
||||
use deno_ast::MediaType;
|
||||
use deno_ast::ModuleSpecifier;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::resolve_url_or_path;
|
||||
use deno_graph::GraphKind;
|
||||
|
@ -330,7 +330,7 @@ async fn resolve_compile_executable_output_path(
|
|||
.map(PathBuf::from)
|
||||
}
|
||||
|
||||
output_path.ok_or_else(|| generic_error(
|
||||
output_path.ok_or_else(|| anyhow!(
|
||||
"An executable name was not provided. One could not be inferred from the URL. Aborting.",
|
||||
)).map(|output_path| {
|
||||
get_os_specific_filepath(output_path, &compile_flags.target)
|
||||
|
|
|
@ -17,7 +17,6 @@ use deno_config::glob::PathOrPattern;
|
|||
use deno_config::glob::PathOrPatternSet;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::sourcemap::SourceMap;
|
||||
|
@ -430,7 +429,7 @@ fn collect_coverages(
|
|||
.ignore_git_folder()
|
||||
.ignore_node_modules()
|
||||
.set_vendor_folder(cli_options.vendor_dir_path().map(ToOwned::to_owned))
|
||||
.collect_file_patterns(&CliSys::default(), file_patterns)?;
|
||||
.collect_file_patterns(&CliSys::default(), file_patterns);
|
||||
|
||||
let coverage_patterns = FilePatterns {
|
||||
base: initial_cwd.to_path_buf(),
|
||||
|
@ -505,7 +504,7 @@ pub fn cover_files(
|
|||
coverage_flags: CoverageFlags,
|
||||
) -> Result<(), AnyError> {
|
||||
if coverage_flags.files.include.is_empty() {
|
||||
return Err(generic_error("No matching coverage profiles found"));
|
||||
return Err(anyhow!("No matching coverage profiles found"));
|
||||
}
|
||||
|
||||
let factory = CliFactory::from_flags(flags);
|
||||
|
@ -527,7 +526,7 @@ pub fn cover_files(
|
|||
cli_options.initial_cwd(),
|
||||
)?;
|
||||
if script_coverages.is_empty() {
|
||||
return Err(generic_error("No coverage files found"));
|
||||
return Err(anyhow!("No coverage files found"));
|
||||
}
|
||||
let script_coverages = filter_coverages(
|
||||
script_coverages,
|
||||
|
@ -536,7 +535,7 @@ pub fn cover_files(
|
|||
in_npm_pkg_checker.as_ref(),
|
||||
);
|
||||
if script_coverages.is_empty() {
|
||||
return Err(generic_error("No covered files included in the report"));
|
||||
return Err(anyhow!("No covered files included in the report"));
|
||||
}
|
||||
|
||||
let proc_coverages: Vec<_> = script_coverages
|
||||
|
|
101
cli/tools/doc.rs
101
cli/tools/doc.rs
|
@ -62,10 +62,11 @@ async fn generate_doc_nodes_for_builtin_types(
|
|||
)],
|
||||
Vec::new(),
|
||||
);
|
||||
let roots = vec![source_file_specifier.clone()];
|
||||
let mut graph = deno_graph::ModuleGraph::new(GraphKind::TypesOnly);
|
||||
graph
|
||||
.build(
|
||||
vec![source_file_specifier.clone()],
|
||||
roots.clone(),
|
||||
&loader,
|
||||
deno_graph::BuildOptions {
|
||||
imports: Vec::new(),
|
||||
|
@ -85,14 +86,13 @@ async fn generate_doc_nodes_for_builtin_types(
|
|||
let doc_parser = doc::DocParser::new(
|
||||
&graph,
|
||||
parser,
|
||||
&roots,
|
||||
doc::DocParserOptions {
|
||||
diagnostics: false,
|
||||
private: doc_flags.private,
|
||||
},
|
||||
)?;
|
||||
let nodes = doc_parser.parse_module(&source_file_specifier)?.definitions;
|
||||
|
||||
Ok(IndexMap::from([(source_file_specifier, nodes)]))
|
||||
Ok(doc_parser.parse()?)
|
||||
}
|
||||
|
||||
pub async fn doc(
|
||||
|
@ -158,19 +158,13 @@ pub async fn doc(
|
|||
let doc_parser = doc::DocParser::new(
|
||||
&graph,
|
||||
&capturing_parser,
|
||||
&module_specifiers,
|
||||
doc::DocParserOptions {
|
||||
private: doc_flags.private,
|
||||
diagnostics: doc_flags.lint,
|
||||
},
|
||||
)?;
|
||||
|
||||
let mut doc_nodes_by_url =
|
||||
IndexMap::with_capacity(module_specifiers.len());
|
||||
|
||||
for module_specifier in module_specifiers {
|
||||
let nodes = doc_parser.parse_with_reexports(&module_specifier)?;
|
||||
doc_nodes_by_url.insert(module_specifier, nodes);
|
||||
}
|
||||
let doc_nodes_by_url = doc_parser.parse()?;
|
||||
|
||||
if doc_flags.lint {
|
||||
let diagnostics = doc_parser.take_diagnostics();
|
||||
|
@ -191,29 +185,9 @@ pub async fn doc(
|
|||
.await?;
|
||||
let (_, deno_ns) = deno_ns.into_iter().next().unwrap();
|
||||
|
||||
let short_path = Rc::new(ShortPath::new(
|
||||
ModuleSpecifier::parse("file:///lib.deno.d.ts").unwrap(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
));
|
||||
|
||||
deno_doc::html::compute_namespaced_symbols(
|
||||
&deno_ns
|
||||
.into_iter()
|
||||
.map(|node| deno_doc::html::DocNodeWithContext {
|
||||
origin: short_path.clone(),
|
||||
ns_qualifiers: Rc::new([]),
|
||||
kind_with_drilldown:
|
||||
deno_doc::html::DocNodeKindWithDrilldown::Other(node.kind()),
|
||||
inner: Rc::new(node),
|
||||
drilldown_name: None,
|
||||
parent: None,
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
Some(deno_ns)
|
||||
} else {
|
||||
Default::default()
|
||||
None
|
||||
};
|
||||
|
||||
let mut main_entrypoint = None;
|
||||
|
@ -393,7 +367,7 @@ impl UsageComposer for DocComposer {
|
|||
fn generate_docs_directory(
|
||||
doc_nodes_by_url: IndexMap<ModuleSpecifier, Vec<doc::DocNode>>,
|
||||
html_options: &DocHtmlFlag,
|
||||
deno_ns: std::collections::HashMap<Vec<String>, Option<Rc<ShortPath>>>,
|
||||
built_in_types: Option<Vec<doc::DocNode>>,
|
||||
rewrite_map: Option<IndexMap<ModuleSpecifier, String>>,
|
||||
main_entrypoint: Option<ModuleSpecifier>,
|
||||
) -> Result<(), AnyError> {
|
||||
|
@ -426,12 +400,12 @@ fn generate_docs_directory(
|
|||
None
|
||||
};
|
||||
|
||||
let options = deno_doc::html::GenerateOptions {
|
||||
let mut options = deno_doc::html::GenerateOptions {
|
||||
package_name: html_options.name.clone(),
|
||||
main_entrypoint,
|
||||
rewrite_map,
|
||||
href_resolver: Rc::new(DocResolver {
|
||||
deno_ns,
|
||||
deno_ns: Default::default(),
|
||||
strip_trailing_html: html_options.strip_trailing_html,
|
||||
}),
|
||||
usage_composer: Rc::new(DocComposer),
|
||||
|
@ -451,7 +425,58 @@ fn generate_docs_directory(
|
|||
})),
|
||||
};
|
||||
|
||||
let mut files = deno_doc::html::generate(options, doc_nodes_by_url)
|
||||
if let Some(built_in_types) = built_in_types {
|
||||
let ctx = deno_doc::html::GenerateCtx::create_basic(
|
||||
deno_doc::html::GenerateOptions {
|
||||
package_name: None,
|
||||
main_entrypoint: Some(
|
||||
ModuleSpecifier::parse("file:///lib.deno.d.ts").unwrap(),
|
||||
),
|
||||
href_resolver: Rc::new(DocResolver {
|
||||
deno_ns: Default::default(),
|
||||
strip_trailing_html: false,
|
||||
}),
|
||||
usage_composer: Rc::new(DocComposer),
|
||||
rewrite_map: Default::default(),
|
||||
category_docs: Default::default(),
|
||||
disable_search: Default::default(),
|
||||
symbol_redirect_map: Default::default(),
|
||||
default_symbol_map: Default::default(),
|
||||
markdown_renderer: deno_doc::html::comrak::create_renderer(
|
||||
None, None, None,
|
||||
),
|
||||
markdown_stripper: Rc::new(deno_doc::html::comrak::strip),
|
||||
head_inject: None,
|
||||
},
|
||||
IndexMap::from([(
|
||||
ModuleSpecifier::parse("file:///lib.deno.d.ts").unwrap(),
|
||||
built_in_types,
|
||||
)]),
|
||||
)?;
|
||||
|
||||
let deno_ns = deno_doc::html::compute_namespaced_symbols(
|
||||
&ctx,
|
||||
Box::new(
|
||||
ctx
|
||||
.doc_nodes
|
||||
.values()
|
||||
.next()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(std::borrow::Cow::Borrowed),
|
||||
),
|
||||
);
|
||||
|
||||
options.href_resolver = Rc::new(DocResolver {
|
||||
deno_ns,
|
||||
strip_trailing_html: html_options.strip_trailing_html,
|
||||
});
|
||||
}
|
||||
|
||||
let ctx =
|
||||
deno_doc::html::GenerateCtx::create_basic(options, doc_nodes_by_url)?;
|
||||
|
||||
let mut files = deno_doc::html::generate(ctx)
|
||||
.context("Failed to generate HTML documentation")?;
|
||||
|
||||
files.insert("prism.js".to_string(), PRISM_JS.to_string());
|
||||
|
|
|
@ -26,7 +26,6 @@ use deno_config::glob::FilePatterns;
|
|||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
|
@ -167,7 +166,7 @@ fn resolve_paths_with_options_batches(
|
|||
Vec::with_capacity(members_fmt_options.len());
|
||||
for (_ctx, member_fmt_options) in members_fmt_options {
|
||||
let files =
|
||||
collect_fmt_files(cli_options, member_fmt_options.files.clone())?;
|
||||
collect_fmt_files(cli_options, member_fmt_options.files.clone());
|
||||
if !files.is_empty() {
|
||||
paths_with_options_batches.push(PathsWithOptions {
|
||||
base: member_fmt_options.files.base.clone(),
|
||||
|
@ -177,7 +176,7 @@ fn resolve_paths_with_options_batches(
|
|||
}
|
||||
}
|
||||
if paths_with_options_batches.is_empty() {
|
||||
return Err(generic_error("No target files found."));
|
||||
return Err(anyhow!("No target files found."));
|
||||
}
|
||||
Ok(paths_with_options_batches)
|
||||
}
|
||||
|
@ -224,7 +223,7 @@ async fn format_files(
|
|||
fn collect_fmt_files(
|
||||
cli_options: &CliOptions,
|
||||
files: FilePatterns,
|
||||
) -> Result<Vec<PathBuf>, AnyError> {
|
||||
) -> Vec<PathBuf> {
|
||||
FileCollector::new(|e| {
|
||||
is_supported_ext_fmt(e.path)
|
||||
|| (e.path.extension().is_none() && cli_options.ext_flag().is_some())
|
||||
|
@ -484,7 +483,7 @@ pub fn format_html(
|
|||
}
|
||||
|
||||
if let Some(error_msg) = inner(&error, file_path) {
|
||||
AnyError::from(generic_error(error_msg))
|
||||
AnyError::msg(error_msg)
|
||||
} else {
|
||||
AnyError::from(error)
|
||||
}
|
||||
|
@ -732,9 +731,9 @@ impl Formatter for CheckFormatter {
|
|||
Ok(())
|
||||
} else {
|
||||
let not_formatted_files_str = files_str(not_formatted_files_count);
|
||||
Err(generic_error(format!(
|
||||
Err(anyhow!(
|
||||
"Found {not_formatted_files_count} not formatted {not_formatted_files_str} in {checked_files_str}",
|
||||
)))
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ use deno_core::error::AnyError;
|
|||
use deno_core::resolve_url_or_path;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::url;
|
||||
use deno_error::JsErrorClass;
|
||||
use deno_graph::Dependency;
|
||||
use deno_graph::GraphKind;
|
||||
use deno_graph::Module;
|
||||
|
@ -664,9 +665,10 @@ impl<'a> GraphDisplayContext<'a> {
|
|||
HttpsChecksumIntegrity(_) => "(checksum integrity error)",
|
||||
Decode(_) => "(loading decode error)",
|
||||
Loader(err) => {
|
||||
match deno_runtime::errors::get_error_class_name(err) {
|
||||
Some("NotCapable") => "(not capable, requires --allow-import)",
|
||||
_ => "(loading error)",
|
||||
if err.get_class() == "NotCapable" {
|
||||
"(not capable, requires --allow-import)"
|
||||
} else {
|
||||
"(loading error)"
|
||||
}
|
||||
}
|
||||
Jsr(_) => "(loading error)",
|
||||
|
|
|
@ -12,9 +12,9 @@ use std::path::PathBuf;
|
|||
use std::sync::Arc;
|
||||
|
||||
use deno_cache_dir::file_fetcher::CacheSetting;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::resolve_url_or_path;
|
||||
use deno_core::url::Url;
|
||||
|
@ -54,9 +54,7 @@ fn validate_name(exec_name: &str) -> Result<(), AnyError> {
|
|||
if EXEC_NAME_RE.is_match(exec_name) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(generic_error(format!(
|
||||
"Invalid executable name: {exec_name}"
|
||||
)))
|
||||
Err(anyhow!("Invalid executable name: {exec_name}"))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,7 +221,7 @@ pub async fn uninstall(
|
|||
// ensure directory exists
|
||||
if let Ok(metadata) = fs::metadata(&installation_dir) {
|
||||
if !metadata.is_dir() {
|
||||
return Err(generic_error("Installation path is not a directory"));
|
||||
return Err(anyhow!("Installation path is not a directory"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,10 +245,10 @@ pub async fn uninstall(
|
|||
}
|
||||
|
||||
if !removed {
|
||||
return Err(generic_error(format!(
|
||||
return Err(anyhow!(
|
||||
"No installation found for {}",
|
||||
uninstall_flags.name
|
||||
)));
|
||||
));
|
||||
}
|
||||
|
||||
// There might be some extra files to delete
|
||||
|
@ -423,14 +421,14 @@ async fn create_install_shim(
|
|||
// ensure directory exists
|
||||
if let Ok(metadata) = fs::metadata(&shim_data.installation_dir) {
|
||||
if !metadata.is_dir() {
|
||||
return Err(generic_error("Installation path is not a directory"));
|
||||
return Err(anyhow!("Installation path is not a directory"));
|
||||
}
|
||||
} else {
|
||||
fs::create_dir_all(&shim_data.installation_dir)?;
|
||||
};
|
||||
|
||||
if shim_data.file_path.exists() && !install_flags_global.force {
|
||||
return Err(generic_error(
|
||||
return Err(anyhow!(
|
||||
"Existing installation found. Aborting (Use -f to overwrite).",
|
||||
));
|
||||
};
|
||||
|
@ -492,7 +490,7 @@ async fn resolve_shim_data(
|
|||
|
||||
let name = match name {
|
||||
Some(name) => name,
|
||||
None => return Err(generic_error(
|
||||
None => return Err(anyhow!(
|
||||
"An executable name was not provided. One could not be inferred from the URL. Aborting.",
|
||||
)),
|
||||
};
|
||||
|
@ -524,9 +522,7 @@ async fn resolve_shim_data(
|
|||
let log_level = match log_level {
|
||||
Level::Debug => "debug",
|
||||
Level::Info => "info",
|
||||
_ => {
|
||||
return Err(generic_error(format!("invalid log level {log_level}")))
|
||||
}
|
||||
_ => return Err(anyhow!(format!("invalid log level {log_level}"))),
|
||||
};
|
||||
executable_args.push(log_level.to_string());
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures::FutureExt;
|
||||
use deno_core::located_script_name;
|
||||
|
@ -137,10 +137,10 @@ pub async fn kernel(
|
|||
}
|
||||
let cwd_url =
|
||||
Url::from_directory_path(cli_options.initial_cwd()).map_err(|_| {
|
||||
generic_error(format!(
|
||||
anyhow!(
|
||||
"Unable to construct URL from the path of cwd: {}",
|
||||
cli_options.initial_cwd().to_string_lossy(),
|
||||
))
|
||||
)
|
||||
})?;
|
||||
repl_session.set_test_reporter_factory(Box::new(move || {
|
||||
Box::new(
|
||||
|
|
|
@ -18,7 +18,6 @@ use deno_config::glob::FileCollector;
|
|||
use deno_config::glob::FilePatterns;
|
||||
use deno_config::workspace::WorkspaceDirectory;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures::future::LocalBoxFuture;
|
||||
use deno_core::futures::FutureExt;
|
||||
|
@ -77,9 +76,7 @@ pub async fn lint(
|
|||
) -> Result<(), AnyError> {
|
||||
if lint_flags.watch.is_some() {
|
||||
if lint_flags.is_stdin() {
|
||||
return Err(generic_error(
|
||||
"Lint watch on standard input is not supported.",
|
||||
));
|
||||
return Err(anyhow!("Lint watch on standard input is not supported.",));
|
||||
}
|
||||
|
||||
return lint_with_watch(flags, lint_flags).await;
|
||||
|
@ -223,7 +220,7 @@ fn resolve_paths_with_options_batches(
|
|||
let mut paths_with_options_batches =
|
||||
Vec::with_capacity(members_lint_options.len());
|
||||
for (dir, lint_options) in members_lint_options {
|
||||
let files = collect_lint_files(cli_options, lint_options.files.clone())?;
|
||||
let files = collect_lint_files(cli_options, lint_options.files.clone());
|
||||
if !files.is_empty() {
|
||||
paths_with_options_batches.push(PathsWithOptions {
|
||||
dir,
|
||||
|
@ -233,7 +230,7 @@ fn resolve_paths_with_options_batches(
|
|||
}
|
||||
}
|
||||
if paths_with_options_batches.is_empty() {
|
||||
return Err(generic_error("No target files found."));
|
||||
return Err(anyhow!("No target files found."));
|
||||
}
|
||||
Ok(paths_with_options_batches)
|
||||
}
|
||||
|
@ -446,7 +443,7 @@ impl WorkspaceLinter {
|
|||
fn collect_lint_files(
|
||||
cli_options: &CliOptions,
|
||||
files: FilePatterns,
|
||||
) -> Result<Vec<PathBuf>, AnyError> {
|
||||
) -> Vec<PathBuf> {
|
||||
FileCollector::new(|e| {
|
||||
is_script_ext(e.path)
|
||||
|| (e.path.extension().is_none() && cli_options.ext_flag().is_some())
|
||||
|
@ -534,7 +531,7 @@ fn lint_stdin(
|
|||
}
|
||||
let mut source_code = String::new();
|
||||
if stdin().read_to_string(&mut source_code).is_err() {
|
||||
return Err(generic_error("Failed to read from stdin"));
|
||||
return Err(anyhow!("Failed to read from stdin"));
|
||||
}
|
||||
|
||||
let linter = CliLinter::new(CliLinterOptions {
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::sync::Arc;
|
|||
|
||||
use deno_ast::SourceRange;
|
||||
use deno_config::workspace::WorkspaceResolver;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_graph::source::ResolutionKind;
|
||||
use deno_graph::source::ResolveError;
|
||||
use deno_graph::Range;
|
||||
|
@ -187,7 +187,7 @@ impl<'a> deno_graph::source::Resolver for SloppyImportCaptureResolver<'a> {
|
|||
let resolution = self
|
||||
.workspace_resolver
|
||||
.resolve(specifier_text, &referrer_range.specifier)
|
||||
.map_err(|err| ResolveError::Other(err.into()))?;
|
||||
.map_err(|err| ResolveError::Other(JsErrorBox::from_err(err)))?;
|
||||
|
||||
match resolution {
|
||||
deno_config::workspace::MappedResolution::Normal {
|
||||
|
@ -220,7 +220,7 @@ impl<'a> deno_graph::source::Resolver for SloppyImportCaptureResolver<'a> {
|
|||
}
|
||||
| deno_config::workspace::MappedResolution::PackageJson { .. } => {
|
||||
// this error is ignored
|
||||
Err(ResolveError::Other(anyhow!("")))
|
||||
Err(ResolveError::Other(JsErrorBox::generic("")))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -233,7 +233,7 @@ pub fn collect_publish_paths(
|
|||
) -> Result<Vec<CollectedPublishPath>, AnyError> {
|
||||
let diagnostics_collector = opts.diagnostics_collector;
|
||||
let publish_paths =
|
||||
collect_paths(opts.cli_options, diagnostics_collector, opts.file_patterns)?;
|
||||
collect_paths(opts.cli_options, diagnostics_collector, opts.file_patterns);
|
||||
let publish_paths_set = publish_paths.iter().cloned().collect::<HashSet<_>>();
|
||||
let capacity = publish_paths.len() + opts.force_include_paths.len();
|
||||
let mut paths = HashSet::with_capacity(capacity);
|
||||
|
@ -321,7 +321,7 @@ fn collect_paths(
|
|||
cli_options: &CliOptions,
|
||||
diagnostics_collector: &PublishDiagnosticsCollector,
|
||||
file_patterns: FilePatterns,
|
||||
) -> Result<Vec<PathBuf>, AnyError> {
|
||||
) -> Vec<PathBuf> {
|
||||
FileCollector::new(|e| {
|
||||
if !e.metadata.file_type().is_file() {
|
||||
if let Ok(specifier) = ModuleSpecifier::from_file_path(e.path) {
|
||||
|
|
|
@ -4,8 +4,10 @@ use std::cell::RefCell;
|
|||
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::error::CoreError;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::Value;
|
||||
use deno_error::JsErrorBox;
|
||||
use tokio::sync::mpsc::channel;
|
||||
use tokio::sync::mpsc::unbounded_channel;
|
||||
use tokio::sync::mpsc::Receiver;
|
||||
|
@ -47,7 +49,7 @@ pub enum RustylineSyncMessage {
|
|||
}
|
||||
|
||||
pub enum RustylineSyncResponse {
|
||||
PostMessage(Result<Value, AnyError>),
|
||||
PostMessage(Result<Value, CoreError>),
|
||||
LspCompletions(Vec<ReplCompletionItem>),
|
||||
}
|
||||
|
||||
|
@ -61,7 +63,7 @@ impl RustylineSyncMessageSender {
|
|||
&self,
|
||||
method: &str,
|
||||
params: Option<T>,
|
||||
) -> Result<Value, AnyError> {
|
||||
) -> Result<Value, CoreError> {
|
||||
if let Err(err) =
|
||||
self
|
||||
.message_tx
|
||||
|
@ -69,10 +71,11 @@ impl RustylineSyncMessageSender {
|
|||
method: method.to_string(),
|
||||
params: params
|
||||
.map(|params| serde_json::to_value(params))
|
||||
.transpose()?,
|
||||
.transpose()
|
||||
.map_err(JsErrorBox::from_err)?,
|
||||
})
|
||||
{
|
||||
Err(anyhow!("{}", err))
|
||||
Err(JsErrorBox::from_err(err).into())
|
||||
} else {
|
||||
match self.response_rx.borrow_mut().blocking_recv().unwrap() {
|
||||
RustylineSyncResponse::PostMessage(result) => result,
|
||||
|
|
|
@ -16,8 +16,9 @@ use deno_ast::ParsedSource;
|
|||
use deno_ast::SourcePos;
|
||||
use deno_ast::SourceRangedForSpanned;
|
||||
use deno_ast::SourceTextInfo;
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::error::CoreError;
|
||||
use deno_core::futures::channel::mpsc::UnboundedReceiver;
|
||||
use deno_core::futures::FutureExt;
|
||||
use deno_core::futures::StreamExt;
|
||||
|
@ -27,6 +28,7 @@ use deno_core::unsync::spawn;
|
|||
use deno_core::url::Url;
|
||||
use deno_core::LocalInspectorSession;
|
||||
use deno_core::PollEventLoopOptions;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_graph::Position;
|
||||
use deno_graph::PositionRange;
|
||||
use deno_graph::SpecifierWithRange;
|
||||
|
@ -250,10 +252,10 @@ impl ReplSession {
|
|||
|
||||
let cwd_url =
|
||||
Url::from_directory_path(cli_options.initial_cwd()).map_err(|_| {
|
||||
generic_error(format!(
|
||||
anyhow!(
|
||||
"Unable to construct URL from the path of cwd: {}",
|
||||
cli_options.initial_cwd().to_string_lossy(),
|
||||
))
|
||||
)
|
||||
})?;
|
||||
let ts_config_for_emit = cli_options
|
||||
.resolve_ts_config_for_emit(deno_config::deno_json::TsConfigType::Emit)?;
|
||||
|
@ -322,7 +324,7 @@ impl ReplSession {
|
|||
&mut self,
|
||||
method: &str,
|
||||
params: Option<T>,
|
||||
) -> Result<Value, AnyError> {
|
||||
) -> Result<Value, CoreError> {
|
||||
self
|
||||
.worker
|
||||
.js_runtime
|
||||
|
@ -339,7 +341,7 @@ impl ReplSession {
|
|||
.await
|
||||
}
|
||||
|
||||
pub async fn run_event_loop(&mut self) -> Result<(), AnyError> {
|
||||
pub async fn run_event_loop(&mut self) -> Result<(), CoreError> {
|
||||
self.worker.run_event_loop(true).await
|
||||
}
|
||||
|
||||
|
@ -400,21 +402,29 @@ impl ReplSession {
|
|||
}
|
||||
Err(err) => {
|
||||
// handle a parsing diagnostic
|
||||
match err.downcast_ref::<deno_ast::ParseDiagnostic>() {
|
||||
match crate::util::result::any_and_jserrorbox_downcast_ref::<
|
||||
deno_ast::ParseDiagnostic,
|
||||
>(&err)
|
||||
{
|
||||
Some(diagnostic) => {
|
||||
Ok(EvaluationOutput::Error(format_diagnostic(diagnostic)))
|
||||
}
|
||||
None => match err.downcast_ref::<ParseDiagnosticsError>() {
|
||||
Some(diagnostics) => Ok(EvaluationOutput::Error(
|
||||
diagnostics
|
||||
.0
|
||||
.iter()
|
||||
.map(format_diagnostic)
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n\n"),
|
||||
)),
|
||||
None => Err(err),
|
||||
},
|
||||
None => {
|
||||
match crate::util::result::any_and_jserrorbox_downcast_ref::<
|
||||
ParseDiagnosticsError,
|
||||
>(&err)
|
||||
{
|
||||
Some(diagnostics) => Ok(EvaluationOutput::Error(
|
||||
diagnostics
|
||||
.0
|
||||
.iter()
|
||||
.map(format_diagnostic)
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n\n"),
|
||||
)),
|
||||
None => Err(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -742,7 +752,7 @@ impl ReplSession {
|
|||
async fn evaluate_expression(
|
||||
&mut self,
|
||||
expression: &str,
|
||||
) -> Result<cdp::EvaluateResponse, AnyError> {
|
||||
) -> Result<cdp::EvaluateResponse, CoreError> {
|
||||
self
|
||||
.post_message_with_event_loop(
|
||||
"Runtime.evaluate",
|
||||
|
@ -765,7 +775,9 @@ impl ReplSession {
|
|||
}),
|
||||
)
|
||||
.await
|
||||
.and_then(|res| serde_json::from_value(res).map_err(|e| e.into()))
|
||||
.and_then(|res| {
|
||||
serde_json::from_value(res).map_err(|e| JsErrorBox::from_err(e).into())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,13 +4,13 @@ use std::collections::HashMap;
|
|||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::error::CoreError;
|
||||
use deno_core::futures::StreamExt;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_core::serde_json::{self};
|
||||
use deno_core::url::Url;
|
||||
use deno_core::LocalInspectorSession;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_terminal::colors;
|
||||
use tokio::select;
|
||||
|
||||
|
@ -66,19 +66,19 @@ pub struct HmrRunner {
|
|||
#[async_trait::async_trait(?Send)]
|
||||
impl crate::worker::HmrRunner for HmrRunner {
|
||||
// TODO(bartlomieju): this code is duplicated in `cli/tools/coverage/mod.rs`
|
||||
async fn start(&mut self) -> Result<(), AnyError> {
|
||||
async fn start(&mut self) -> Result<(), CoreError> {
|
||||
self.enable_debugger().await
|
||||
}
|
||||
|
||||
// TODO(bartlomieju): this code is duplicated in `cli/tools/coverage/mod.rs`
|
||||
async fn stop(&mut self) -> Result<(), AnyError> {
|
||||
async fn stop(&mut self) -> Result<(), CoreError> {
|
||||
self
|
||||
.watcher_communicator
|
||||
.change_restart_mode(WatcherRestartMode::Automatic);
|
||||
self.disable_debugger().await
|
||||
}
|
||||
|
||||
async fn run(&mut self) -> Result<(), AnyError> {
|
||||
async fn run(&mut self) -> Result<(), CoreError> {
|
||||
self
|
||||
.watcher_communicator
|
||||
.change_restart_mode(WatcherRestartMode::Manual);
|
||||
|
@ -87,13 +87,13 @@ impl crate::worker::HmrRunner for HmrRunner {
|
|||
select! {
|
||||
biased;
|
||||
Some(notification) = session_rx.next() => {
|
||||
let notification = serde_json::from_value::<cdp::Notification>(notification)?;
|
||||
let notification = serde_json::from_value::<cdp::Notification>(notification).map_err(JsErrorBox::from_err)?;
|
||||
if notification.method == "Runtime.exceptionThrown" {
|
||||
let exception_thrown = serde_json::from_value::<cdp::ExceptionThrown>(notification.params)?;
|
||||
let exception_thrown = serde_json::from_value::<cdp::ExceptionThrown>(notification.params).map_err(JsErrorBox::from_err)?;
|
||||
let (message, description) = exception_thrown.exception_details.get_message_and_description();
|
||||
break Err(generic_error(format!("{} {}", message, description)));
|
||||
break Err(JsErrorBox::generic(format!("{} {}", message, description)).into());
|
||||
} else if notification.method == "Debugger.scriptParsed" {
|
||||
let params = serde_json::from_value::<cdp::ScriptParsed>(notification.params)?;
|
||||
let params = serde_json::from_value::<cdp::ScriptParsed>(notification.params).map_err(JsErrorBox::from_err)?;
|
||||
if params.url.starts_with("file://") {
|
||||
let file_url = Url::parse(¶ms.url).unwrap();
|
||||
let file_path = file_url.to_file_path().unwrap();
|
||||
|
@ -105,7 +105,7 @@ impl crate::worker::HmrRunner for HmrRunner {
|
|||
}
|
||||
}
|
||||
changed_paths = self.watcher_communicator.watch_for_changed_paths() => {
|
||||
let changed_paths = changed_paths?;
|
||||
let changed_paths = changed_paths.map_err(JsErrorBox::from_err)?;
|
||||
|
||||
let Some(changed_paths) = changed_paths else {
|
||||
let _ = self.watcher_communicator.force_restart();
|
||||
|
@ -187,7 +187,7 @@ impl HmrRunner {
|
|||
}
|
||||
|
||||
// TODO(bartlomieju): this code is duplicated in `cli/tools/coverage/mod.rs`
|
||||
async fn enable_debugger(&mut self) -> Result<(), AnyError> {
|
||||
async fn enable_debugger(&mut self) -> Result<(), CoreError> {
|
||||
self
|
||||
.session
|
||||
.post_message::<()>("Debugger.enable", None)
|
||||
|
@ -200,7 +200,7 @@ impl HmrRunner {
|
|||
}
|
||||
|
||||
// TODO(bartlomieju): this code is duplicated in `cli/tools/coverage/mod.rs`
|
||||
async fn disable_debugger(&mut self) -> Result<(), AnyError> {
|
||||
async fn disable_debugger(&mut self) -> Result<(), CoreError> {
|
||||
self
|
||||
.session
|
||||
.post_message::<()>("Debugger.disable", None)
|
||||
|
@ -216,7 +216,7 @@ impl HmrRunner {
|
|||
&mut self,
|
||||
script_id: &str,
|
||||
source: &str,
|
||||
) -> Result<cdp::SetScriptSourceResponse, AnyError> {
|
||||
) -> Result<cdp::SetScriptSourceResponse, CoreError> {
|
||||
let result = self
|
||||
.session
|
||||
.post_message(
|
||||
|
@ -229,15 +229,16 @@ impl HmrRunner {
|
|||
)
|
||||
.await?;
|
||||
|
||||
Ok(serde_json::from_value::<cdp::SetScriptSourceResponse>(
|
||||
result,
|
||||
)?)
|
||||
Ok(
|
||||
serde_json::from_value::<cdp::SetScriptSourceResponse>(result)
|
||||
.map_err(JsErrorBox::from_err)?,
|
||||
)
|
||||
}
|
||||
|
||||
async fn dispatch_hmr_event(
|
||||
&mut self,
|
||||
script_id: &str,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), CoreError> {
|
||||
let expr = format!(
|
||||
"dispatchEvent(new CustomEvent(\"hmr\", {{ detail: {{ path: \"{}\" }} }}));",
|
||||
script_id
|
||||
|
|
|
@ -73,7 +73,7 @@ async fn do_serve(
|
|||
)
|
||||
.await?;
|
||||
let worker_count = match worker_count {
|
||||
None | Some(1) => return worker.run().await,
|
||||
None | Some(1) => return worker.run().await.map_err(Into::into),
|
||||
Some(c) => c,
|
||||
};
|
||||
|
||||
|
@ -133,7 +133,7 @@ async fn run_worker(
|
|||
worker.run_for_watcher().await?;
|
||||
Ok(0)
|
||||
} else {
|
||||
worker.run().await
|
||||
worker.run().await.map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,8 @@ const HALF_SYNC_MARKER: &[u8; 4] = &[226, 128, 139, 0];
|
|||
const BUFFER_SIZE: usize = 4096;
|
||||
|
||||
/// The test channel has been closed and cannot be used to send further messages.
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, deno_error::JsError)]
|
||||
#[class(generic)]
|
||||
pub struct ChannelClosedError;
|
||||
|
||||
impl std::error::Error for ChannelClosedError {}
|
||||
|
|
|
@ -25,10 +25,9 @@ use deno_cache_dir::file_fetcher::File;
|
|||
use deno_config::glob::FilePatterns;
|
||||
use deno_config::glob::WalkEntry;
|
||||
use deno_core::anyhow;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::anyhow::Context as _;
|
||||
use deno_core::error::generic_error;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::error::CoreError;
|
||||
use deno_core::error::JsError;
|
||||
use deno_core::futures::future;
|
||||
use deno_core::futures::stream;
|
||||
|
@ -49,6 +48,7 @@ use deno_core::v8;
|
|||
use deno_core::ModuleSpecifier;
|
||||
use deno_core::OpState;
|
||||
use deno_core::PollEventLoopOptions;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_runtime::deno_io::Stdio;
|
||||
use deno_runtime::deno_io::StdioPipe;
|
||||
use deno_runtime::deno_permissions::Permissions;
|
||||
|
@ -106,6 +106,8 @@ use reporters::PrettyTestReporter;
|
|||
use reporters::TapTestReporter;
|
||||
use reporters::TestReporter;
|
||||
|
||||
use crate::tools::test::channel::ChannelClosedError;
|
||||
|
||||
/// How many times we're allowed to spin the event loop before considering something a leak.
|
||||
const MAX_SANITIZER_LOOP_SPINS: usize = 16;
|
||||
|
||||
|
@ -612,7 +614,7 @@ async fn configure_main_worker(
|
|||
permissions_container: PermissionsContainer,
|
||||
worker_sender: TestEventWorkerSender,
|
||||
options: &TestSpecifierOptions,
|
||||
) -> Result<(Option<Box<dyn CoverageCollector>>, MainWorker), anyhow::Error> {
|
||||
) -> Result<(Option<Box<dyn CoverageCollector>>, MainWorker), CoreError> {
|
||||
let mut worker = worker_factory
|
||||
.create_custom_worker(
|
||||
WorkerExecutionMode::Test,
|
||||
|
@ -640,21 +642,15 @@ async fn configure_main_worker(
|
|||
let mut worker = worker.into_main_worker();
|
||||
match res {
|
||||
Ok(()) => Ok(()),
|
||||
Err(error) => {
|
||||
// TODO(mmastrac): It would be nice to avoid having this error pattern repeated
|
||||
if error.is::<JsError>() {
|
||||
send_test_event(
|
||||
&worker.js_runtime.op_state(),
|
||||
TestEvent::UncaughtError(
|
||||
specifier.to_string(),
|
||||
Box::new(error.downcast::<JsError>().unwrap()),
|
||||
),
|
||||
)?;
|
||||
Ok(())
|
||||
} else {
|
||||
Err(error)
|
||||
}
|
||||
Err(CoreError::Js(err)) => {
|
||||
send_test_event(
|
||||
&worker.js_runtime.op_state(),
|
||||
TestEvent::UncaughtError(specifier.to_string(), Box::new(err)),
|
||||
)
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
Ok(())
|
||||
}
|
||||
Err(err) => Err(err),
|
||||
}?;
|
||||
Ok((coverage_collector, worker))
|
||||
}
|
||||
|
@ -691,21 +687,14 @@ pub async fn test_specifier(
|
|||
.await
|
||||
{
|
||||
Ok(()) => Ok(()),
|
||||
Err(error) => {
|
||||
// TODO(mmastrac): It would be nice to avoid having this error pattern repeated
|
||||
if error.is::<JsError>() {
|
||||
send_test_event(
|
||||
&worker.js_runtime.op_state(),
|
||||
TestEvent::UncaughtError(
|
||||
specifier.to_string(),
|
||||
Box::new(error.downcast::<JsError>().unwrap()),
|
||||
),
|
||||
)?;
|
||||
Ok(())
|
||||
} else {
|
||||
Err(error)
|
||||
}
|
||||
Err(CoreError::Js(err)) => {
|
||||
send_test_event(
|
||||
&worker.js_runtime.op_state(),
|
||||
TestEvent::UncaughtError(specifier.to_string(), Box::new(err)),
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => Err(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -718,7 +707,7 @@ async fn test_specifier_inner(
|
|||
specifier: ModuleSpecifier,
|
||||
fail_fast_tracker: FailFastTracker,
|
||||
options: TestSpecifierOptions,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), CoreError> {
|
||||
// Ensure that there are no pending exceptions before we start running tests
|
||||
worker.run_up_to_duration(Duration::from_millis(0)).await?;
|
||||
|
||||
|
@ -765,7 +754,7 @@ pub fn worker_has_tests(worker: &mut MainWorker) -> bool {
|
|||
/// Yields to tokio to allow async work to process, and then polls
|
||||
/// the event loop once.
|
||||
#[must_use = "The event loop result should be checked"]
|
||||
pub async fn poll_event_loop(worker: &mut MainWorker) -> Result<(), AnyError> {
|
||||
pub async fn poll_event_loop(worker: &mut MainWorker) -> Result<(), CoreError> {
|
||||
// Allow any ops that to do work in the tokio event loop to do so
|
||||
tokio::task::yield_now().await;
|
||||
// Spin the event loop once
|
||||
|
@ -784,13 +773,11 @@ pub async fn poll_event_loop(worker: &mut MainWorker) -> Result<(), AnyError> {
|
|||
pub fn send_test_event(
|
||||
op_state: &RefCell<OpState>,
|
||||
event: TestEvent,
|
||||
) -> Result<(), AnyError> {
|
||||
Ok(
|
||||
op_state
|
||||
.borrow_mut()
|
||||
.borrow_mut::<TestEventSender>()
|
||||
.send(event)?,
|
||||
)
|
||||
) -> Result<(), ChannelClosedError> {
|
||||
op_state
|
||||
.borrow_mut()
|
||||
.borrow_mut::<TestEventSender>()
|
||||
.send(event)
|
||||
}
|
||||
|
||||
pub async fn run_tests_for_worker(
|
||||
|
@ -986,13 +973,10 @@ async fn run_tests_for_worker_inner(
|
|||
let result = match result {
|
||||
Ok(r) => r,
|
||||
Err(error) => {
|
||||
if error.is::<JsError>() {
|
||||
if let CoreError::Js(js_error) = error {
|
||||
send_test_event(
|
||||
&state_rc,
|
||||
TestEvent::UncaughtError(
|
||||
specifier.to_string(),
|
||||
Box::new(error.downcast::<JsError>().unwrap()),
|
||||
),
|
||||
TestEvent::UncaughtError(specifier.to_string(), Box::new(js_error)),
|
||||
)?;
|
||||
fail_fast_tracker.add_failure();
|
||||
send_test_event(
|
||||
|
@ -1002,7 +986,7 @@ async fn run_tests_for_worker_inner(
|
|||
had_uncaught_error = true;
|
||||
continue;
|
||||
} else {
|
||||
return Err(error);
|
||||
return Err(error.into());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1374,25 +1358,20 @@ pub async fn report_tests(
|
|||
reporter.report_summary(&elapsed, &tests, &test_steps);
|
||||
if let Err(err) = reporter.flush_report(&elapsed, &tests, &test_steps) {
|
||||
return (
|
||||
Err(generic_error(format!(
|
||||
"Test reporter failed to flush: {}",
|
||||
err
|
||||
))),
|
||||
Err(anyhow!("Test reporter failed to flush: {}", err)),
|
||||
receiver,
|
||||
);
|
||||
}
|
||||
|
||||
if used_only {
|
||||
return (
|
||||
Err(generic_error(
|
||||
"Test failed because the \"only\" option was used",
|
||||
)),
|
||||
Err(anyhow!("Test failed because the \"only\" option was used",)),
|
||||
receiver,
|
||||
);
|
||||
}
|
||||
|
||||
if failed {
|
||||
return (Err(generic_error("Test failed")), receiver);
|
||||
return (Err(anyhow!("Test failed")), receiver);
|
||||
}
|
||||
|
||||
(Ok(()), receiver)
|
||||
|
@ -1575,7 +1554,7 @@ pub async fn run_tests(
|
|||
|
||||
if !workspace_test_options.permit_no_files && specifiers_with_mode.is_empty()
|
||||
{
|
||||
return Err(generic_error("No test modules found"));
|
||||
return Err(anyhow!("No test modules found"));
|
||||
}
|
||||
|
||||
let doc_tests = get_doc_tests(&specifiers_with_mode, file_fetcher).await?;
|
||||
|
@ -1611,10 +1590,10 @@ pub async fn run_tests(
|
|||
TestSpecifiersOptions {
|
||||
cwd: Url::from_directory_path(cli_options.initial_cwd()).map_err(
|
||||
|_| {
|
||||
generic_error(format!(
|
||||
anyhow!(
|
||||
"Unable to construct URL from the path of cwd: {}",
|
||||
cli_options.initial_cwd().to_string_lossy(),
|
||||
))
|
||||
)
|
||||
},
|
||||
)?,
|
||||
concurrent_jobs: workspace_test_options.concurrent_jobs,
|
||||
|
@ -1793,10 +1772,10 @@ pub async fn run_tests_with_watch(
|
|||
TestSpecifiersOptions {
|
||||
cwd: Url::from_directory_path(cli_options.initial_cwd()).map_err(
|
||||
|_| {
|
||||
generic_error(format!(
|
||||
anyhow!(
|
||||
"Unable to construct URL from the path of cwd: {}",
|
||||
cli_options.initial_cwd().to_string_lossy(),
|
||||
))
|
||||
)
|
||||
},
|
||||
)?,
|
||||
concurrent_jobs: workspace_test_options.concurrent_jobs,
|
||||
|
|
|
@ -129,7 +129,7 @@ impl TestReporter for CompoundTestReporter {
|
|||
if errors.is_empty() {
|
||||
Ok(())
|
||||
} else {
|
||||
bail!(
|
||||
anyhow::bail!(
|
||||
"error in one or more wrapped reporters:\n{}",
|
||||
errors
|
||||
.iter()
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
use std::collections::VecDeque;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use deno_core::anyhow::Context;
|
||||
|
||||
use super::fmt::to_relative_path_or_remote_url;
|
||||
use super::*;
|
||||
|
||||
|
|
|
@ -320,7 +320,8 @@ impl fmt::Display for Diagnostic {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, deno_error::JsError)]
|
||||
#[class(generic)]
|
||||
pub struct Diagnostics(Vec<Diagnostic>);
|
||||
|
||||
impl Diagnostics {
|
||||
|
|
119
cli/tsc/mod.rs
119
cli/tsc/mod.rs
|
@ -3,12 +3,10 @@
|
|||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_ast::MediaType;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::ascii_str;
|
||||
use deno_core::error::AnyError;
|
||||
|
@ -454,13 +452,6 @@ impl State {
|
|||
}
|
||||
}
|
||||
|
||||
fn normalize_specifier(
|
||||
specifier: &str,
|
||||
current_dir: &Path,
|
||||
) -> Result<ModuleSpecifier, AnyError> {
|
||||
resolve_url_or_path(specifier, current_dir).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
#[op2]
|
||||
#[string]
|
||||
fn op_create_hash(s: &mut OpState, #[string] text: &str) -> String {
|
||||
|
@ -531,6 +522,21 @@ pub fn as_ts_script_kind(media_type: MediaType) -> i32 {
|
|||
pub const MISSING_DEPENDENCY_SPECIFIER: &str =
|
||||
"internal:///missing_dependency.d.ts";
|
||||
|
||||
#[derive(Debug, Error, deno_error::JsError)]
|
||||
pub enum LoadError {
|
||||
#[class(generic)]
|
||||
#[error("Unable to load {path}: {error}")]
|
||||
LoadFromNodeModule { path: String, error: std::io::Error },
|
||||
#[class(inherit)]
|
||||
#[error(
|
||||
"Error converting a string module specifier for \"op_resolve\": {0}"
|
||||
)]
|
||||
ModuleResolution(#[from] deno_core::ModuleResolutionError),
|
||||
#[class(inherit)]
|
||||
#[error("{0}")]
|
||||
ClosestPkgJson(#[from] node_resolver::errors::ClosestPkgJsonError),
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct LoadResponse {
|
||||
|
@ -545,24 +551,28 @@ struct LoadResponse {
|
|||
fn op_load(
|
||||
state: &mut OpState,
|
||||
#[string] load_specifier: &str,
|
||||
) -> Result<Option<LoadResponse>, AnyError> {
|
||||
) -> Result<Option<LoadResponse>, LoadError> {
|
||||
op_load_inner(state, load_specifier)
|
||||
}
|
||||
|
||||
fn op_load_inner(
|
||||
state: &mut OpState,
|
||||
load_specifier: &str,
|
||||
) -> Result<Option<LoadResponse>, AnyError> {
|
||||
) -> Result<Option<LoadResponse>, LoadError> {
|
||||
fn load_from_node_modules(
|
||||
specifier: &ModuleSpecifier,
|
||||
npm_state: Option<&RequestNpmState>,
|
||||
media_type: &mut MediaType,
|
||||
is_cjs: &mut bool,
|
||||
) -> Result<String, AnyError> {
|
||||
) -> Result<String, LoadError> {
|
||||
*media_type = MediaType::from_specifier(specifier);
|
||||
let file_path = specifier.to_file_path().unwrap();
|
||||
let code = std::fs::read_to_string(&file_path)
|
||||
.with_context(|| format!("Unable to load {}", file_path.display()))?;
|
||||
let code = std::fs::read_to_string(&file_path).map_err(|err| {
|
||||
LoadError::LoadFromNodeModule {
|
||||
path: file_path.display().to_string(),
|
||||
error: err,
|
||||
}
|
||||
})?;
|
||||
let code: Arc<str> = code.into();
|
||||
*is_cjs = npm_state
|
||||
.map(|npm_state| {
|
||||
|
@ -575,8 +585,7 @@ fn op_load_inner(
|
|||
|
||||
let state = state.borrow_mut::<State>();
|
||||
|
||||
let specifier = normalize_specifier(load_specifier, &state.current_dir)
|
||||
.context("Error converting a string module specifier for \"op_load\".")?;
|
||||
let specifier = resolve_url_or_path(load_specifier, &state.current_dir)?;
|
||||
|
||||
let mut hash: Option<String> = None;
|
||||
let mut media_type = MediaType::Unknown;
|
||||
|
@ -688,6 +697,26 @@ fn op_load_inner(
|
|||
}))
|
||||
}
|
||||
|
||||
#[derive(Debug, Error, deno_error::JsError)]
|
||||
pub enum ResolveError {
|
||||
#[class(inherit)]
|
||||
#[error(
|
||||
"Error converting a string module specifier for \"op_resolve\": {0}"
|
||||
)]
|
||||
ModuleResolution(#[from] deno_core::ModuleResolutionError),
|
||||
#[class(inherit)]
|
||||
#[error("{0}")]
|
||||
PackageSubpathResolve(PackageSubpathResolveError),
|
||||
#[class(inherit)]
|
||||
#[error("{0}")]
|
||||
ResolvePkgFolderFromDenoModule(
|
||||
#[from] crate::npm::ResolvePkgFolderFromDenoModuleError,
|
||||
),
|
||||
#[class(inherit)]
|
||||
#[error("{0}")]
|
||||
ResolveNonGraphSpecifierTypes(#[from] ResolveNonGraphSpecifierTypesError),
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ResolveArgs {
|
||||
|
@ -717,7 +746,7 @@ fn op_resolve(
|
|||
state: &mut OpState,
|
||||
#[string] base: String,
|
||||
#[serde] specifiers: Vec<(bool, String)>,
|
||||
) -> Result<Vec<(String, &'static str)>, AnyError> {
|
||||
) -> Result<Vec<(String, &'static str)>, ResolveError> {
|
||||
op_resolve_inner(state, ResolveArgs { base, specifiers })
|
||||
}
|
||||
|
||||
|
@ -725,7 +754,7 @@ fn op_resolve(
|
|||
fn op_resolve_inner(
|
||||
state: &mut OpState,
|
||||
args: ResolveArgs,
|
||||
) -> Result<Vec<(String, &'static str)>, AnyError> {
|
||||
) -> Result<Vec<(String, &'static str)>, ResolveError> {
|
||||
let state = state.borrow_mut::<State>();
|
||||
let mut resolved: Vec<(String, &'static str)> =
|
||||
Vec::with_capacity(args.specifiers.len());
|
||||
|
@ -734,9 +763,7 @@ fn op_resolve_inner(
|
|||
{
|
||||
remapped_specifier.clone()
|
||||
} else {
|
||||
normalize_specifier(&args.base, &state.current_dir).context(
|
||||
"Error converting a string module specifier for \"op_resolve\".",
|
||||
)?
|
||||
resolve_url_or_path(&args.base, &state.current_dir)?
|
||||
};
|
||||
let referrer_module = state.graph.get(&referrer);
|
||||
for (is_cjs, specifier) in args.specifiers {
|
||||
|
@ -852,7 +879,7 @@ fn resolve_graph_specifier_types(
|
|||
referrer: &ModuleSpecifier,
|
||||
resolution_mode: ResolutionMode,
|
||||
state: &State,
|
||||
) -> Result<Option<(ModuleSpecifier, MediaType)>, AnyError> {
|
||||
) -> Result<Option<(ModuleSpecifier, MediaType)>, ResolveError> {
|
||||
let graph = &state.graph;
|
||||
let maybe_module = match graph.try_get(specifier) {
|
||||
Ok(Some(module)) => Some(module),
|
||||
|
@ -914,7 +941,7 @@ fn resolve_graph_specifier_types(
|
|||
Err(err) => match err.code() {
|
||||
NodeJsErrorCode::ERR_TYPES_NOT_FOUND
|
||||
| NodeJsErrorCode::ERR_MODULE_NOT_FOUND => None,
|
||||
_ => return Err(err.into()),
|
||||
_ => return Err(ResolveError::PackageSubpathResolve(err)),
|
||||
},
|
||||
};
|
||||
Ok(Some(into_specifier_and_media_type(maybe_url)))
|
||||
|
@ -936,10 +963,12 @@ fn resolve_graph_specifier_types(
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
enum ResolveNonGraphSpecifierTypesError {
|
||||
#[derive(Debug, Error, deno_error::JsError)]
|
||||
pub enum ResolveNonGraphSpecifierTypesError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
ResolvePkgFolderFromDenoReq(#[from] ResolvePkgFolderFromDenoReqError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
PackageSubpathResolve(#[from] PackageSubpathResolveError),
|
||||
}
|
||||
|
@ -1036,10 +1065,20 @@ fn op_respond_inner(state: &mut OpState, args: RespondArgs) {
|
|||
state.maybe_response = Some(args);
|
||||
}
|
||||
|
||||
#[derive(Debug, Error, deno_error::JsError)]
|
||||
pub enum ExecError {
|
||||
#[class(generic)]
|
||||
#[error("The response for the exec request was not set.")]
|
||||
ResponseNotSet,
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Core(deno_core::error::CoreError),
|
||||
}
|
||||
|
||||
/// Execute a request on the supplied snapshot, returning a response which
|
||||
/// contains information, like any emitted files, diagnostics, statistics and
|
||||
/// optionally an updated TypeScript build info.
|
||||
pub fn exec(request: Request) -> Result<Response, AnyError> {
|
||||
pub fn exec(request: Request) -> Result<Response, ExecError> {
|
||||
// tsc cannot handle root specifiers that don't have one of the "acceptable"
|
||||
// extensions. Therefore, we have to check the root modules against their
|
||||
// extensions and remap any that are unacceptable to tsc and add them to the
|
||||
|
@ -1115,7 +1154,9 @@ pub fn exec(request: Request) -> Result<Response, AnyError> {
|
|||
..Default::default()
|
||||
});
|
||||
|
||||
runtime.execute_script(located_script_name!(), exec_source)?;
|
||||
runtime
|
||||
.execute_script(located_script_name!(), exec_source)
|
||||
.map_err(ExecError::Core)?;
|
||||
|
||||
let op_state = runtime.op_state();
|
||||
let mut op_state = op_state.borrow_mut();
|
||||
|
@ -1132,7 +1173,7 @@ pub fn exec(request: Request) -> Result<Response, AnyError> {
|
|||
stats,
|
||||
})
|
||||
} else {
|
||||
Err(anyhow!("The response for the exec request was not set."))
|
||||
Err(ExecError::ResponseNotSet)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1141,6 +1182,7 @@ mod tests {
|
|||
use deno_core::futures::future;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::OpState;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_graph::GraphKind;
|
||||
use deno_graph::ModuleGraph;
|
||||
use test_util::PathRef;
|
||||
|
@ -1167,13 +1209,20 @@ mod tests {
|
|||
.replace("://", "_")
|
||||
.replace('/', "-");
|
||||
let source_path = self.fixtures.join(specifier_text);
|
||||
let response = source_path.read_to_bytes_if_exists().map(|c| {
|
||||
Some(deno_graph::source::LoadResponse::Module {
|
||||
specifier: specifier.clone(),
|
||||
maybe_headers: None,
|
||||
content: c.into(),
|
||||
let response = source_path
|
||||
.read_to_bytes_if_exists()
|
||||
.map(|c| {
|
||||
Some(deno_graph::source::LoadResponse::Module {
|
||||
specifier: specifier.clone(),
|
||||
maybe_headers: None,
|
||||
content: c.into(),
|
||||
})
|
||||
})
|
||||
});
|
||||
.map_err(|e| {
|
||||
deno_graph::source::LoadError::Other(Arc::new(JsErrorBox::generic(
|
||||
e.to_string(),
|
||||
)))
|
||||
});
|
||||
Box::pin(future::ready(response))
|
||||
}
|
||||
}
|
||||
|
@ -1210,7 +1259,7 @@ mod tests {
|
|||
|
||||
async fn test_exec(
|
||||
specifier: &ModuleSpecifier,
|
||||
) -> Result<Response, AnyError> {
|
||||
) -> Result<Response, ExecError> {
|
||||
let hash_data = 123; // something random
|
||||
let fixtures = test_util::testdata_path().join("tsc2");
|
||||
let loader = MockLoader { fixtures };
|
||||
|
|
|
@ -10,7 +10,7 @@ use std::time::Duration;
|
|||
|
||||
use deno_config::glob::PathOrPatternSet;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::error::JsError;
|
||||
use deno_core::error::CoreError;
|
||||
use deno_core::futures::Future;
|
||||
use deno_core::futures::FutureExt;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
|
@ -23,6 +23,7 @@ use notify::RecommendedWatcher;
|
|||
use notify::RecursiveMode;
|
||||
use notify::Watcher;
|
||||
use tokio::select;
|
||||
use tokio::sync::broadcast::error::RecvError;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::sync::mpsc::UnboundedReceiver;
|
||||
use tokio::time::sleep;
|
||||
|
@ -80,10 +81,13 @@ where
|
|||
{
|
||||
let result = watch_future.await;
|
||||
if let Err(err) = result {
|
||||
let error_string = match err.downcast_ref::<JsError>() {
|
||||
Some(e) => format_js_error(e),
|
||||
None => format!("{err:?}"),
|
||||
};
|
||||
let error_string =
|
||||
match crate::util::result::any_and_jserrorbox_downcast_ref::<CoreError>(
|
||||
&err,
|
||||
) {
|
||||
Some(CoreError::Js(e)) => format_js_error(e),
|
||||
_ => format!("{err:?}"),
|
||||
};
|
||||
log::error!(
|
||||
"{}: {}",
|
||||
colors::red_bold("error"),
|
||||
|
@ -171,9 +175,9 @@ impl WatcherCommunicator {
|
|||
|
||||
pub async fn watch_for_changed_paths(
|
||||
&self,
|
||||
) -> Result<Option<Vec<PathBuf>>, AnyError> {
|
||||
) -> Result<Option<Vec<PathBuf>>, RecvError> {
|
||||
let mut rx = self.changed_paths_rx.resubscribe();
|
||||
rx.recv().await.map_err(AnyError::from)
|
||||
rx.recv().await
|
||||
}
|
||||
|
||||
pub fn change_restart_mode(&self, restart_mode: WatcherRestartMode) {
|
||||
|
|
|
@ -13,7 +13,6 @@ use deno_config::glob::PathOrPattern;
|
|||
use deno_config::glob::PathOrPatternSet;
|
||||
use deno_config::glob::WalkEntry;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::unsync::spawn_blocking;
|
||||
use deno_core::ModuleSpecifier;
|
||||
|
@ -129,7 +128,7 @@ pub fn collect_specifiers(
|
|||
.ignore_git_folder()
|
||||
.ignore_node_modules()
|
||||
.set_vendor_folder(vendor_folder)
|
||||
.collect_file_patterns(&CliSys::default(), files)?;
|
||||
.collect_file_patterns(&CliSys::default(), files);
|
||||
let mut collected_files_as_urls = collected_files
|
||||
.iter()
|
||||
.map(|f| specifier_from_file_path(f).unwrap())
|
||||
|
@ -169,7 +168,7 @@ pub fn clone_dir_recursive<
|
|||
sys: &TSys,
|
||||
from: &Path,
|
||||
to: &Path,
|
||||
) -> Result<(), AnyError> {
|
||||
) -> Result<(), CopyDirRecursiveError> {
|
||||
if cfg!(target_vendor = "apple") {
|
||||
if let Some(parent) = to.parent() {
|
||||
sys.fs_create_dir_all(parent)?;
|
||||
|
@ -200,6 +199,47 @@ pub fn clone_dir_recursive<
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum CopyDirRecursiveError {
|
||||
#[class(inherit)]
|
||||
#[error("Creating {path}")]
|
||||
Creating {
|
||||
path: PathBuf,
|
||||
#[source]
|
||||
#[inherit]
|
||||
source: Error,
|
||||
},
|
||||
#[class(inherit)]
|
||||
#[error("Creating {path}")]
|
||||
Reading {
|
||||
path: PathBuf,
|
||||
#[source]
|
||||
#[inherit]
|
||||
source: Error,
|
||||
},
|
||||
#[class(inherit)]
|
||||
#[error("Dir {from} to {to}")]
|
||||
Dir {
|
||||
from: PathBuf,
|
||||
to: PathBuf,
|
||||
#[source]
|
||||
#[inherit]
|
||||
source: Box<Self>,
|
||||
},
|
||||
#[class(inherit)]
|
||||
#[error("Copying {from} to {to}")]
|
||||
Copying {
|
||||
from: PathBuf,
|
||||
to: PathBuf,
|
||||
#[source]
|
||||
#[inherit]
|
||||
source: Error,
|
||||
},
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Other(#[from] Error),
|
||||
}
|
||||
|
||||
/// Copies a directory to another directory.
|
||||
///
|
||||
/// Note: Does not handle symlinks.
|
||||
|
@ -213,13 +253,20 @@ pub fn copy_dir_recursive<
|
|||
sys: &TSys,
|
||||
from: &Path,
|
||||
to: &Path,
|
||||
) -> Result<(), AnyError> {
|
||||
sys
|
||||
.fs_create_dir_all(to)
|
||||
.with_context(|| format!("Creating {}", to.display()))?;
|
||||
let read_dir = sys
|
||||
.fs_read_dir(from)
|
||||
.with_context(|| format!("Reading {}", from.display()))?;
|
||||
) -> Result<(), CopyDirRecursiveError> {
|
||||
sys.fs_create_dir_all(to).map_err(|source| {
|
||||
CopyDirRecursiveError::Creating {
|
||||
path: to.to_path_buf(),
|
||||
source,
|
||||
}
|
||||
})?;
|
||||
let read_dir =
|
||||
sys
|
||||
.fs_read_dir(from)
|
||||
.map_err(|source| CopyDirRecursiveError::Reading {
|
||||
path: from.to_path_buf(),
|
||||
source,
|
||||
})?;
|
||||
|
||||
for entry in read_dir {
|
||||
let entry = entry?;
|
||||
|
@ -228,12 +275,20 @@ pub fn copy_dir_recursive<
|
|||
let new_to = to.join(entry.file_name());
|
||||
|
||||
if file_type.is_dir() {
|
||||
copy_dir_recursive(sys, &new_from, &new_to).with_context(|| {
|
||||
format!("Dir {} to {}", new_from.display(), new_to.display())
|
||||
copy_dir_recursive(sys, &new_from, &new_to).map_err(|source| {
|
||||
CopyDirRecursiveError::Dir {
|
||||
from: new_from.to_path_buf(),
|
||||
to: new_to.to_path_buf(),
|
||||
source: Box::new(source),
|
||||
}
|
||||
})?;
|
||||
} else if file_type.is_file() {
|
||||
sys.fs_copy(&new_from, &new_to).with_context(|| {
|
||||
format!("Copying {} to {}", new_from.display(), new_to.display())
|
||||
sys.fs_copy(&new_from, &new_to).map_err(|source| {
|
||||
CopyDirRecursiveError::Copying {
|
||||
from: new_from.to_path_buf(),
|
||||
to: new_to.to_path_buf(),
|
||||
source,
|
||||
}
|
||||
})?;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,13 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::convert::Infallible;
|
||||
use std::fmt::Debug;
|
||||
use std::fmt::Display;
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::error::CoreError;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_error::JsErrorClass;
|
||||
|
||||
pub trait InfallibleResultExt<T> {
|
||||
fn unwrap_infallible(self) -> T;
|
||||
|
@ -14,3 +21,23 @@ impl<T> InfallibleResultExt<T> for Result<T, Infallible> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn any_and_jserrorbox_downcast_ref<
|
||||
E: Display + Debug + Send + Sync + 'static,
|
||||
>(
|
||||
err: &AnyError,
|
||||
) -> Option<&E> {
|
||||
err
|
||||
.downcast_ref::<E>()
|
||||
.or_else(|| {
|
||||
err
|
||||
.downcast_ref::<JsErrorBox>()
|
||||
.and_then(|e| e.as_any().downcast_ref::<E>())
|
||||
})
|
||||
.or_else(|| {
|
||||
err.downcast_ref::<CoreError>().and_then(|e| match e {
|
||||
CoreError::JsNative(e) => e.as_any().downcast_ref::<E>(),
|
||||
_ => None,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ use std::sync::Arc;
|
|||
use deno_ast::ModuleSpecifier;
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::error::CoreError;
|
||||
use deno_core::futures::FutureExt;
|
||||
use deno_core::url::Url;
|
||||
use deno_core::v8;
|
||||
|
@ -17,6 +18,7 @@ use deno_core::FeatureChecker;
|
|||
use deno_core::ModuleLoader;
|
||||
use deno_core::PollEventLoopOptions;
|
||||
use deno_core::SharedArrayBufferStore;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_runtime::code_cache;
|
||||
use deno_runtime::deno_broadcast_channel::InMemoryBroadcastChannel;
|
||||
use deno_runtime::deno_fs;
|
||||
|
@ -50,7 +52,6 @@ use crate::args::CliLockfile;
|
|||
use crate::args::DenoSubcommand;
|
||||
use crate::args::NpmCachingStrategy;
|
||||
use crate::args::StorageKeyResolver;
|
||||
use crate::errors;
|
||||
use crate::node::CliNodeResolver;
|
||||
use crate::node::CliPackageJsonResolver;
|
||||
use crate::npm::CliNpmResolver;
|
||||
|
@ -80,9 +81,9 @@ pub trait ModuleLoaderFactory: Send + Sync {
|
|||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
pub trait HmrRunner: Send + Sync {
|
||||
async fn start(&mut self) -> Result<(), AnyError>;
|
||||
async fn stop(&mut self) -> Result<(), AnyError>;
|
||||
async fn run(&mut self) -> Result<(), AnyError>;
|
||||
async fn start(&mut self) -> Result<(), CoreError>;
|
||||
async fn stop(&mut self) -> Result<(), CoreError>;
|
||||
async fn run(&mut self) -> Result<(), CoreError>;
|
||||
}
|
||||
|
||||
pub trait CliCodeCache: code_cache::CodeCache {
|
||||
|
@ -195,7 +196,7 @@ impl CliMainWorker {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn run(&mut self) -> Result<i32, AnyError> {
|
||||
pub async fn run(&mut self) -> Result<i32, CoreError> {
|
||||
let mut maybe_coverage_collector =
|
||||
self.maybe_setup_coverage_collector().await?;
|
||||
let mut maybe_hmr_runner = self.maybe_setup_hmr_runner().await?;
|
||||
|
@ -216,7 +217,7 @@ impl CliMainWorker {
|
|||
let result;
|
||||
select! {
|
||||
hmr_result = hmr_future => {
|
||||
result = hmr_result;
|
||||
result = hmr_result.map_err(Into::into);
|
||||
},
|
||||
event_loop_result = event_loop_future => {
|
||||
result = event_loop_result;
|
||||
|
@ -331,12 +332,12 @@ impl CliMainWorker {
|
|||
executor.execute().await
|
||||
}
|
||||
|
||||
pub async fn execute_main_module(&mut self) -> Result<(), AnyError> {
|
||||
pub async fn execute_main_module(&mut self) -> Result<(), CoreError> {
|
||||
let id = self.worker.preload_main_module(&self.main_module).await?;
|
||||
self.worker.evaluate_module(id).await
|
||||
}
|
||||
|
||||
pub async fn execute_side_module(&mut self) -> Result<(), AnyError> {
|
||||
pub async fn execute_side_module(&mut self) -> Result<(), CoreError> {
|
||||
let id = self.worker.preload_side_module(&self.main_module).await?;
|
||||
self.worker.evaluate_module(id).await
|
||||
}
|
||||
|
@ -393,7 +394,7 @@ impl CliMainWorker {
|
|||
&mut self,
|
||||
name: &'static str,
|
||||
source_code: &'static str,
|
||||
) -> Result<v8::Global<v8::Value>, AnyError> {
|
||||
) -> Result<v8::Global<v8::Value>, CoreError> {
|
||||
self.worker.js_runtime.execute_script(name, source_code)
|
||||
}
|
||||
}
|
||||
|
@ -465,7 +466,7 @@ impl CliMainWorkerFactory {
|
|||
&self,
|
||||
mode: WorkerExecutionMode,
|
||||
main_module: ModuleSpecifier,
|
||||
) -> Result<CliMainWorker, AnyError> {
|
||||
) -> Result<CliMainWorker, CoreError> {
|
||||
self
|
||||
.create_custom_worker(
|
||||
mode,
|
||||
|
@ -484,7 +485,7 @@ impl CliMainWorkerFactory {
|
|||
permissions: PermissionsContainer,
|
||||
custom_extensions: Vec<Extension>,
|
||||
stdio: deno_runtime::deno_io::Stdio,
|
||||
) -> Result<CliMainWorker, AnyError> {
|
||||
) -> Result<CliMainWorker, CoreError> {
|
||||
let shared = &self.shared;
|
||||
let CreateModuleLoaderResult {
|
||||
module_loader,
|
||||
|
@ -513,16 +514,15 @@ impl CliMainWorkerFactory {
|
|||
}
|
||||
|
||||
// use a fake referrer that can be used to discover the package.json if necessary
|
||||
let referrer =
|
||||
ModuleSpecifier::from_directory_path(self.shared.fs.cwd()?)
|
||||
.unwrap()
|
||||
.join("package.json")?;
|
||||
let referrer = ModuleSpecifier::from_directory_path(
|
||||
self.shared.fs.cwd().map_err(JsErrorBox::from_err)?,
|
||||
)
|
||||
.unwrap()
|
||||
.join("package.json")?;
|
||||
let package_folder = shared
|
||||
.npm_resolver
|
||||
.resolve_pkg_folder_from_deno_module_req(
|
||||
package_ref.req(),
|
||||
&referrer,
|
||||
)?;
|
||||
.resolve_pkg_folder_from_deno_module_req(package_ref.req(), &referrer)
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
let main_module = self
|
||||
.resolve_binary_entrypoint(&package_folder, package_ref.sub_path())?;
|
||||
|
||||
|
@ -633,7 +633,6 @@ impl CliMainWorkerFactory {
|
|||
should_break_on_first_statement: shared.options.inspect_brk,
|
||||
should_wait_for_inspector_session: shared.options.inspect_wait,
|
||||
strace_ops: shared.options.strace_ops.clone(),
|
||||
get_error_class_fn: Some(&errors::get_error_class_name),
|
||||
cache_storage_dir,
|
||||
origin_storage_dir,
|
||||
stdio,
|
||||
|
@ -834,7 +833,6 @@ fn create_web_worker_callback(
|
|||
create_web_worker_cb,
|
||||
format_js_error_fn: Some(Arc::new(format_js_error)),
|
||||
worker_type: args.worker_type,
|
||||
get_error_class_fn: Some(&errors::get_error_class_name),
|
||||
stdio: stdio.clone(),
|
||||
cache_storage_dir,
|
||||
strace_ops: shared.options.strace_ops.clone(),
|
||||
|
|
|
@ -16,6 +16,7 @@ path = "lib.rs"
|
|||
[dependencies]
|
||||
async-trait.workspace = true
|
||||
deno_core.workspace = true
|
||||
deno_error.workspace = true
|
||||
thiserror.workspace = true
|
||||
tokio.workspace = true
|
||||
uuid.workspace = true
|
||||
|
|
|
@ -12,6 +12,7 @@ use deno_core::JsBuffer;
|
|||
use deno_core::OpState;
|
||||
use deno_core::Resource;
|
||||
use deno_core::ResourceId;
|
||||
use deno_error::JsErrorBox;
|
||||
pub use in_memory_broadcast_channel::InMemoryBroadcastChannel;
|
||||
pub use in_memory_broadcast_channel::InMemoryBroadcastChannelResource;
|
||||
use tokio::sync::broadcast::error::SendError as BroadcastSendError;
|
||||
|
@ -19,18 +20,26 @@ use tokio::sync::mpsc::error::SendError as MpscSendError;
|
|||
|
||||
pub const UNSTABLE_FEATURE_NAME: &str = "broadcast-channel";
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum BroadcastChannelError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Resource(deno_core::error::AnyError),
|
||||
Resource(
|
||||
#[from]
|
||||
#[inherit]
|
||||
deno_core::error::ResourceError,
|
||||
),
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
MPSCSendError(MpscSendError<Box<dyn std::fmt::Debug + Send + Sync>>),
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
BroadcastSendError(
|
||||
BroadcastSendError<Box<dyn std::fmt::Debug + Send + Sync>>,
|
||||
),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Other(deno_core::error::AnyError),
|
||||
Other(#[inherit] JsErrorBox),
|
||||
}
|
||||
|
||||
impl<T: std::fmt::Debug + Send + Sync + 'static> From<MpscSendError<T>>
|
||||
|
@ -100,10 +109,7 @@ pub fn op_broadcast_unsubscribe<BC>(
|
|||
where
|
||||
BC: BroadcastChannel + 'static,
|
||||
{
|
||||
let resource = state
|
||||
.resource_table
|
||||
.get::<BC::Resource>(rid)
|
||||
.map_err(BroadcastChannelError::Resource)?;
|
||||
let resource = state.resource_table.get::<BC::Resource>(rid)?;
|
||||
let bc = state.borrow::<BC>();
|
||||
bc.unsubscribe(&resource)
|
||||
}
|
||||
|
@ -118,11 +124,7 @@ pub async fn op_broadcast_send<BC>(
|
|||
where
|
||||
BC: BroadcastChannel + 'static,
|
||||
{
|
||||
let resource = state
|
||||
.borrow()
|
||||
.resource_table
|
||||
.get::<BC::Resource>(rid)
|
||||
.map_err(BroadcastChannelError::Resource)?;
|
||||
let resource = state.borrow().resource_table.get::<BC::Resource>(rid)?;
|
||||
let bc = state.borrow().borrow::<BC>().clone();
|
||||
bc.send(&resource, name, buf.to_vec()).await
|
||||
}
|
||||
|
@ -136,11 +138,7 @@ pub async fn op_broadcast_recv<BC>(
|
|||
where
|
||||
BC: BroadcastChannel + 'static,
|
||||
{
|
||||
let resource = state
|
||||
.borrow()
|
||||
.resource_table
|
||||
.get::<BC::Resource>(rid)
|
||||
.map_err(BroadcastChannelError::Resource)?;
|
||||
let resource = state.borrow().resource_table.get::<BC::Resource>(rid)?;
|
||||
let bc = state.borrow().borrow::<BC>().clone();
|
||||
bc.recv(&resource).await
|
||||
}
|
||||
|
|
1
ext/cache/Cargo.toml
vendored
1
ext/cache/Cargo.toml
vendored
|
@ -16,6 +16,7 @@ path = "lib.rs"
|
|||
[dependencies]
|
||||
async-trait.workspace = true
|
||||
deno_core.workspace = true
|
||||
deno_error.workspace = true
|
||||
rusqlite.workspace = true
|
||||
serde.workspace = true
|
||||
sha2.workspace = true
|
||||
|
|
27
ext/cache/lib.rs
vendored
27
ext/cache/lib.rs
vendored
|
@ -6,7 +6,6 @@ use std::rc::Rc;
|
|||
use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::op2;
|
||||
use deno_core::serde::Deserialize;
|
||||
use deno_core::serde::Serialize;
|
||||
|
@ -14,22 +13,38 @@ use deno_core::ByteString;
|
|||
use deno_core::OpState;
|
||||
use deno_core::Resource;
|
||||
use deno_core::ResourceId;
|
||||
use deno_error::JsErrorBox;
|
||||
|
||||
mod sqlite;
|
||||
pub use sqlite::SqliteBackedCache;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum CacheError {
|
||||
#[class(type)]
|
||||
#[error("CacheStorage is not available in this context")]
|
||||
ContextUnsupported,
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
Sqlite(#[from] rusqlite::Error),
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
JoinError(#[from] tokio::task::JoinError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Resource(deno_core::error::AnyError),
|
||||
Resource(#[from] deno_core::error::ResourceError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Other(deno_core::error::AnyError),
|
||||
Other(JsErrorBox),
|
||||
#[class(inherit)]
|
||||
#[error("{0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
#[class(generic)]
|
||||
#[error("Failed to create cache storage directory {}", .dir.display())]
|
||||
CacheStorageDirectory {
|
||||
dir: PathBuf,
|
||||
#[source]
|
||||
source: std::io::Error,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -237,9 +252,7 @@ where
|
|||
state.put(cache);
|
||||
Ok(state.borrow::<CA>().clone())
|
||||
} else {
|
||||
Err(CacheError::Other(type_error(
|
||||
"CacheStorage is not available in this context",
|
||||
)))
|
||||
Err(CacheError::ContextUnsupported)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
21
ext/cache/sqlite.rs
vendored
21
ext/cache/sqlite.rs
vendored
|
@ -8,8 +8,6 @@ use std::time::SystemTime;
|
|||
use std::time::UNIX_EPOCH;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use deno_core::anyhow::Context;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures::future::poll_fn;
|
||||
use deno_core::parking_lot::Mutex;
|
||||
use deno_core::unsync::spawn_blocking;
|
||||
|
@ -45,14 +43,12 @@ pub struct SqliteBackedCache {
|
|||
impl SqliteBackedCache {
|
||||
pub fn new(cache_storage_dir: PathBuf) -> Result<Self, CacheError> {
|
||||
{
|
||||
std::fs::create_dir_all(&cache_storage_dir)
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"Failed to create cache storage directory {}",
|
||||
cache_storage_dir.display()
|
||||
)
|
||||
})
|
||||
.map_err(CacheError::Other)?;
|
||||
std::fs::create_dir_all(&cache_storage_dir).map_err(|source| {
|
||||
CacheError::CacheStorageDirectory {
|
||||
dir: cache_storage_dir.clone(),
|
||||
source,
|
||||
}
|
||||
})?;
|
||||
let path = cache_storage_dir.join("cache_metadata.db");
|
||||
let connection = rusqlite::Connection::open(&path).unwrap_or_else(|_| {
|
||||
panic!("failed to open cache db at {}", path.display())
|
||||
|
@ -385,7 +381,10 @@ impl CacheResponseResource {
|
|||
}
|
||||
}
|
||||
|
||||
async fn read(self: Rc<Self>, data: &mut [u8]) -> Result<usize, AnyError> {
|
||||
async fn read(
|
||||
self: Rc<Self>,
|
||||
data: &mut [u8],
|
||||
) -> Result<usize, std::io::Error> {
|
||||
let resource = deno_core::RcRef::map(&self, |r| &r.file);
|
||||
let mut file = resource.borrow_mut().await;
|
||||
let nread = file.read(data).await?;
|
||||
|
|
|
@ -15,6 +15,7 @@ path = "lib.rs"
|
|||
|
||||
[dependencies]
|
||||
deno_core.workspace = true
|
||||
deno_error.workspace = true
|
||||
deno_webgpu.workspace = true
|
||||
image = { version = "0.24.7", default-features = false, features = ["png"] }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
|
|
|
@ -12,10 +12,12 @@ use image::RgbaImage;
|
|||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum CanvasError {
|
||||
#[class(type)]
|
||||
#[error("Color type '{0:?}' not supported")]
|
||||
UnsupportedColorType(ColorType),
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
Image(#[from] image::ImageError),
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ anyhow.workspace = true
|
|||
async-trait.workspace = true
|
||||
chrono = { workspace = true, features = ["now"] }
|
||||
deno_core.workspace = true
|
||||
deno_error.workspace = true
|
||||
saffron.workspace = true
|
||||
thiserror.workspace = true
|
||||
tokio.workspace = true
|
||||
|
|
|
@ -7,11 +7,12 @@ use std::borrow::Cow;
|
|||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use deno_core::error::get_custom_error_class;
|
||||
use deno_core::op2;
|
||||
use deno_core::OpState;
|
||||
use deno_core::Resource;
|
||||
use deno_core::ResourceId;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_error::JsErrorClass;
|
||||
|
||||
pub use crate::interface::*;
|
||||
|
||||
|
@ -47,26 +48,35 @@ impl<EH: CronHandle + 'static> Resource for CronResource<EH> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum CronError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Resource(deno_core::error::AnyError),
|
||||
Resource(#[from] deno_core::error::ResourceError),
|
||||
#[class(type)]
|
||||
#[error("Cron name cannot exceed 64 characters: current length {0}")]
|
||||
NameExceeded(usize),
|
||||
#[class(type)]
|
||||
#[error("Invalid cron name: only alphanumeric characters, whitespace, hyphens, and underscores are allowed")]
|
||||
NameInvalid,
|
||||
#[class(type)]
|
||||
#[error("Cron with this name already exists")]
|
||||
AlreadyExists,
|
||||
#[class(type)]
|
||||
#[error("Too many crons")]
|
||||
TooManyCrons,
|
||||
#[class(type)]
|
||||
#[error("Invalid cron schedule")]
|
||||
InvalidCron,
|
||||
#[class(type)]
|
||||
#[error("Invalid backoff schedule")]
|
||||
InvalidBackoff,
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
AcquireError(#[from] tokio::sync::AcquireError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Other(deno_core::error::AnyError),
|
||||
Other(JsErrorBox),
|
||||
}
|
||||
|
||||
#[op2]
|
||||
|
@ -119,7 +129,7 @@ where
|
|||
let resource = match state.resource_table.get::<CronResource<C::EH>>(rid) {
|
||||
Ok(resource) => resource,
|
||||
Err(err) => {
|
||||
if get_custom_error_class(&err) == Some("BadResource") {
|
||||
if err.get_class() == "BadResource" {
|
||||
return Ok(false);
|
||||
} else {
|
||||
return Err(CronError::Resource(err));
|
||||
|
|
|
@ -23,6 +23,7 @@ const-oid = "0.9.0"
|
|||
ctr = "0.9.1"
|
||||
curve25519-dalek = "4.1.3"
|
||||
deno_core.workspace = true
|
||||
deno_error.workspace = true
|
||||
deno_web.workspace = true
|
||||
ed448-goldilocks = { version = "0.8.3", features = ["zeroize"] }
|
||||
elliptic-curve = { version = "0.13.1", features = ["std", "pem"] }
|
||||
|
|
|
@ -70,26 +70,40 @@ pub enum DecryptAlgorithm {
|
|||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum DecryptError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
General(#[from] SharedError),
|
||||
General(
|
||||
#[from]
|
||||
#[inherit]
|
||||
SharedError,
|
||||
),
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
Pkcs1(#[from] rsa::pkcs1::Error),
|
||||
#[class("DOMExceptionOperationError")]
|
||||
#[error("Decryption failed")]
|
||||
Failed,
|
||||
#[class(type)]
|
||||
#[error("invalid length")]
|
||||
InvalidLength,
|
||||
#[class(type)]
|
||||
#[error("invalid counter length. Currently supported 32/64/128 bits")]
|
||||
InvalidCounterLength,
|
||||
#[class(type)]
|
||||
#[error("tag length not equal to 128")]
|
||||
InvalidTagLength,
|
||||
#[class("DOMExceptionOperationError")]
|
||||
#[error("invalid key or iv")]
|
||||
InvalidKeyOrIv,
|
||||
#[class("DOMExceptionOperationError")]
|
||||
#[error("tried to decrypt too much data")]
|
||||
TooMuchData,
|
||||
#[class(type)]
|
||||
#[error("iv length not equal to 12 or 16")]
|
||||
InvalidIvLength,
|
||||
#[class("DOMExceptionOperationError")]
|
||||
#[error("{0}")]
|
||||
Rsa(rsa::Error),
|
||||
}
|
||||
|
|
|
@ -13,12 +13,15 @@ use spki::der::asn1::BitString;
|
|||
use spki::der::Decode;
|
||||
use spki::der::Encode;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum Ed25519Error {
|
||||
#[class("DOMExceptionOperationError")]
|
||||
#[error("Failed to export key")]
|
||||
FailedExport,
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
Der(#[from] rsa::pkcs1::der::Error),
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
KeyRejected(#[from] ring::error::KeyRejected),
|
||||
}
|
||||
|
|
|
@ -71,20 +71,31 @@ pub enum EncryptAlgorithm {
|
|||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum EncryptError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
General(#[from] SharedError),
|
||||
General(
|
||||
#[from]
|
||||
#[inherit]
|
||||
SharedError,
|
||||
),
|
||||
#[class(type)]
|
||||
#[error("invalid length")]
|
||||
InvalidLength,
|
||||
#[class("DOMExceptionOperationError")]
|
||||
#[error("invalid key or iv")]
|
||||
InvalidKeyOrIv,
|
||||
#[class(type)]
|
||||
#[error("iv length not equal to 12 or 16")]
|
||||
InvalidIvLength,
|
||||
#[class(type)]
|
||||
#[error("invalid counter length. Currently supported 32/64/128 bits")]
|
||||
InvalidCounterLength,
|
||||
#[class("DOMExceptionOperationError")]
|
||||
#[error("tried to encrypt too much data")]
|
||||
TooMuchData,
|
||||
#[class("DOMExceptionOperationError")]
|
||||
#[error("Encryption failed")]
|
||||
Failed,
|
||||
}
|
||||
|
|
|
@ -20,12 +20,19 @@ use spki::AlgorithmIdentifierOwned;
|
|||
|
||||
use crate::shared::*;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum ExportKeyError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
General(#[from] SharedError),
|
||||
General(
|
||||
#[from]
|
||||
#[inherit]
|
||||
SharedError,
|
||||
),
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
Der(#[from] spki::der::Error),
|
||||
#[class("DOMExceptionNotSupportedError")]
|
||||
#[error("Unsupported named curve")]
|
||||
UnsupportedNamedCurve,
|
||||
}
|
||||
|
|
|
@ -15,10 +15,16 @@ use serde::Deserialize;
|
|||
|
||||
use crate::shared::*;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
#[class("DOMExceptionOperationError")]
|
||||
pub enum GenerateKeyError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
General(#[from] SharedError),
|
||||
General(
|
||||
#[from]
|
||||
#[inherit]
|
||||
SharedError,
|
||||
),
|
||||
#[error("Bad public exponent")]
|
||||
BadPublicExponent,
|
||||
#[error("Invalid HMAC key length")]
|
||||
|
|
|
@ -14,10 +14,16 @@ use spki::der::Decode;
|
|||
|
||||
use crate::shared::*;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
#[class("DOMExceptionDataError")]
|
||||
pub enum ImportKeyError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
General(#[from] SharedError),
|
||||
General(
|
||||
#[from]
|
||||
#[inherit]
|
||||
SharedError,
|
||||
),
|
||||
#[error("invalid modulus")]
|
||||
InvalidModulus,
|
||||
#[error("invalid public exponent")]
|
||||
|
|
|
@ -8,12 +8,12 @@ use aes_kw::KekAes192;
|
|||
use aes_kw::KekAes256;
|
||||
use base64::prelude::BASE64_URL_SAFE_NO_PAD;
|
||||
use base64::Engine;
|
||||
use deno_core::error::not_supported;
|
||||
use deno_core::op2;
|
||||
use deno_core::unsync::spawn_blocking;
|
||||
use deno_core::JsBuffer;
|
||||
use deno_core::OpState;
|
||||
use deno_core::ToJsBuffer;
|
||||
use deno_error::JsErrorBox;
|
||||
use p256::elliptic_curve::sec1::FromEncodedPoint;
|
||||
use p256::pkcs8::DecodePrivateKey;
|
||||
pub use rand;
|
||||
|
@ -129,63 +129,99 @@ deno_core::extension!(deno_crypto,
|
|||
},
|
||||
);
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum CryptoError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
General(#[from] SharedError),
|
||||
General(
|
||||
#[from]
|
||||
#[inherit]
|
||||
SharedError,
|
||||
),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
JoinError(#[from] tokio::task::JoinError),
|
||||
JoinError(
|
||||
#[from]
|
||||
#[inherit]
|
||||
tokio::task::JoinError,
|
||||
),
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
Der(#[from] rsa::pkcs1::der::Error),
|
||||
#[class(type)]
|
||||
#[error("Missing argument hash")]
|
||||
MissingArgumentHash,
|
||||
#[class(type)]
|
||||
#[error("Missing argument saltLength")]
|
||||
MissingArgumentSaltLength,
|
||||
#[class(type)]
|
||||
#[error("unsupported algorithm")]
|
||||
UnsupportedAlgorithm,
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
KeyRejected(#[from] ring::error::KeyRejected),
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
RSA(#[from] rsa::Error),
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
Pkcs1(#[from] rsa::pkcs1::Error),
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
Unspecified(#[from] ring::error::Unspecified),
|
||||
#[class(type)]
|
||||
#[error("Invalid key format")]
|
||||
InvalidKeyFormat,
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
P256Ecdsa(#[from] p256::ecdsa::Error),
|
||||
#[class(type)]
|
||||
#[error("Unexpected error decoding private key")]
|
||||
DecodePrivateKey,
|
||||
#[class(type)]
|
||||
#[error("Missing argument publicKey")]
|
||||
MissingArgumentPublicKey,
|
||||
#[class(type)]
|
||||
#[error("Missing argument namedCurve")]
|
||||
MissingArgumentNamedCurve,
|
||||
#[class(type)]
|
||||
#[error("Missing argument info")]
|
||||
MissingArgumentInfo,
|
||||
#[class("DOMExceptionOperationError")]
|
||||
#[error("The length provided for HKDF is too large")]
|
||||
HKDFLengthTooLarge,
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
Base64Decode(#[from] base64::DecodeError),
|
||||
#[class(type)]
|
||||
#[error("Data must be multiple of 8 bytes")]
|
||||
DataInvalidSize,
|
||||
#[class(type)]
|
||||
#[error("Invalid key length")]
|
||||
InvalidKeyLength,
|
||||
#[class("DOMExceptionOperationError")]
|
||||
#[error("encryption error")]
|
||||
EncryptionError,
|
||||
#[class("DOMExceptionOperationError")]
|
||||
#[error("decryption error - integrity check failed")]
|
||||
DecryptionError,
|
||||
#[class("DOMExceptionQuotaExceededError")]
|
||||
#[error("The ArrayBufferView's byte length ({0}) exceeds the number of bytes of entropy available via this API (65536)")]
|
||||
ArrayBufferViewLengthExceeded(usize),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Other(deno_core::error::AnyError),
|
||||
Other(
|
||||
#[from]
|
||||
#[inherit]
|
||||
JsErrorBox,
|
||||
),
|
||||
}
|
||||
|
||||
#[op2]
|
||||
#[serde]
|
||||
pub fn op_crypto_base64url_decode(
|
||||
#[string] data: String,
|
||||
) -> Result<ToJsBuffer, Error> {
|
||||
) -> Result<ToJsBuffer, CryptoError> {
|
||||
let data: Vec<u8> = BASE64_URL_SAFE_NO_PAD.decode(data)?;
|
||||
Ok(data.into())
|
||||
}
|
||||
|
@ -201,9 +237,9 @@ pub fn op_crypto_base64url_encode(#[buffer] data: JsBuffer) -> String {
|
|||
pub fn op_crypto_get_random_values(
|
||||
state: &mut OpState,
|
||||
#[buffer] out: &mut [u8],
|
||||
) -> Result<(), Error> {
|
||||
) -> Result<(), CryptoError> {
|
||||
if out.len() > 65536 {
|
||||
return Err(Error::ArrayBufferViewLengthExceeded(out.len()));
|
||||
return Err(CryptoError::ArrayBufferViewLengthExceeded(out.len()));
|
||||
}
|
||||
|
||||
let maybe_seeded_rng = state.try_borrow_mut::<StdRng>();
|
||||
|
@ -255,7 +291,7 @@ pub struct SignArg {
|
|||
pub async fn op_crypto_sign_key(
|
||||
#[serde] args: SignArg,
|
||||
#[buffer] zero_copy: JsBuffer,
|
||||
) -> Result<ToJsBuffer, Error> {
|
||||
) -> Result<ToJsBuffer, CryptoError> {
|
||||
deno_core::unsync::spawn_blocking(move || {
|
||||
let data = &*zero_copy;
|
||||
let algorithm = args.algorithm;
|
||||
|
@ -264,7 +300,7 @@ pub async fn op_crypto_sign_key(
|
|||
Algorithm::RsassaPkcs1v15 => {
|
||||
use rsa::pkcs1v15::SigningKey;
|
||||
let private_key = RsaPrivateKey::from_pkcs1_der(&args.key.data)?;
|
||||
match args.hash.ok_or_else(|| Error::MissingArgumentHash)? {
|
||||
match args.hash.ok_or_else(|| CryptoError::MissingArgumentHash)? {
|
||||
CryptoHash::Sha1 => {
|
||||
let signing_key = SigningKey::<Sha1>::new(private_key);
|
||||
signing_key.sign(data)
|
||||
|
@ -289,11 +325,11 @@ pub async fn op_crypto_sign_key(
|
|||
|
||||
let salt_len = args
|
||||
.salt_length
|
||||
.ok_or_else(|| Error::MissingArgumentSaltLength)?
|
||||
.ok_or_else(|| CryptoError::MissingArgumentSaltLength)?
|
||||
as usize;
|
||||
|
||||
let mut rng = OsRng;
|
||||
match args.hash.ok_or_else(|| Error::MissingArgumentHash)? {
|
||||
match args.hash.ok_or_else(|| CryptoError::MissingArgumentHash)? {
|
||||
CryptoHash::Sha1 => {
|
||||
let signing_key = Pss::new_with_salt::<Sha1>(salt_len);
|
||||
let hashed = Sha1::digest(data);
|
||||
|
@ -320,7 +356,7 @@ pub async fn op_crypto_sign_key(
|
|||
Algorithm::Ecdsa => {
|
||||
let curve: &EcdsaSigningAlgorithm = args
|
||||
.named_curve
|
||||
.ok_or_else(|| Error::Other(not_supported()))?
|
||||
.ok_or_else(JsErrorBox::not_supported)?
|
||||
.into();
|
||||
|
||||
let rng = RingRand::SystemRandom::new();
|
||||
|
@ -330,7 +366,7 @@ pub async fn op_crypto_sign_key(
|
|||
if let Some(hash) = args.hash {
|
||||
match hash {
|
||||
CryptoHash::Sha256 | CryptoHash::Sha384 => (),
|
||||
_ => return Err(Error::UnsupportedAlgorithm),
|
||||
_ => return Err(CryptoError::UnsupportedAlgorithm),
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -340,17 +376,15 @@ pub async fn op_crypto_sign_key(
|
|||
signature.as_ref().to_vec()
|
||||
}
|
||||
Algorithm::Hmac => {
|
||||
let hash: HmacAlgorithm = args
|
||||
.hash
|
||||
.ok_or_else(|| Error::Other(not_supported()))?
|
||||
.into();
|
||||
let hash: HmacAlgorithm =
|
||||
args.hash.ok_or_else(JsErrorBox::not_supported)?.into();
|
||||
|
||||
let key = HmacKey::new(hash, &args.key.data);
|
||||
|
||||
let signature = ring::hmac::sign(&key, data);
|
||||
signature.as_ref().to_vec()
|
||||
}
|
||||
_ => return Err(Error::UnsupportedAlgorithm),
|
||||
_ => return Err(CryptoError::UnsupportedAlgorithm),
|
||||
};
|
||||
|
||||
Ok(signature.into())
|
||||
|
@ -373,7 +407,7 @@ pub struct VerifyArg {
|
|||
pub async fn op_crypto_verify_key(
|
||||
#[serde] args: VerifyArg,
|
||||
#[buffer] zero_copy: JsBuffer,
|
||||
) -> Result<bool, Error> {
|
||||
) -> Result<bool, CryptoError> {
|
||||
deno_core::unsync::spawn_blocking(move || {
|
||||
let data = &*zero_copy;
|
||||
let algorithm = args.algorithm;
|
||||
|
@ -384,7 +418,7 @@ pub async fn op_crypto_verify_key(
|
|||
use rsa::pkcs1v15::VerifyingKey;
|
||||
let public_key = read_rsa_public_key(args.key)?;
|
||||
let signature: Signature = args.signature.as_ref().try_into()?;
|
||||
match args.hash.ok_or_else(|| Error::MissingArgumentHash)? {
|
||||
match args.hash.ok_or_else(|| CryptoError::MissingArgumentHash)? {
|
||||
CryptoHash::Sha1 => {
|
||||
let verifying_key = VerifyingKey::<Sha1>::new(public_key);
|
||||
verifying_key.verify(data, &signature).is_ok()
|
||||
|
@ -409,10 +443,10 @@ pub async fn op_crypto_verify_key(
|
|||
|
||||
let salt_len = args
|
||||
.salt_length
|
||||
.ok_or_else(|| Error::MissingArgumentSaltLength)?
|
||||
.ok_or_else(|| CryptoError::MissingArgumentSaltLength)?
|
||||
as usize;
|
||||
|
||||
match args.hash.ok_or_else(|| Error::MissingArgumentHash)? {
|
||||
match args.hash.ok_or_else(|| CryptoError::MissingArgumentHash)? {
|
||||
CryptoHash::Sha1 => {
|
||||
let pss = Pss::new_with_salt::<Sha1>(salt_len);
|
||||
let hashed = Sha1::digest(data);
|
||||
|
@ -436,21 +470,19 @@ pub async fn op_crypto_verify_key(
|
|||
}
|
||||
}
|
||||
Algorithm::Hmac => {
|
||||
let hash: HmacAlgorithm = args
|
||||
.hash
|
||||
.ok_or_else(|| Error::Other(not_supported()))?
|
||||
.into();
|
||||
let hash: HmacAlgorithm =
|
||||
args.hash.ok_or_else(JsErrorBox::not_supported)?.into();
|
||||
let key = HmacKey::new(hash, &args.key.data);
|
||||
ring::hmac::verify(&key, data, &args.signature).is_ok()
|
||||
}
|
||||
Algorithm::Ecdsa => {
|
||||
let signing_alg: &EcdsaSigningAlgorithm = args
|
||||
.named_curve
|
||||
.ok_or_else(|| Error::Other(not_supported()))?
|
||||
.ok_or_else(JsErrorBox::not_supported)?
|
||||
.into();
|
||||
let verify_alg: &EcdsaVerificationAlgorithm = args
|
||||
.named_curve
|
||||
.ok_or_else(|| Error::Other(not_supported()))?
|
||||
.ok_or_else(JsErrorBox::not_supported)?
|
||||
.into();
|
||||
|
||||
let private_key;
|
||||
|
@ -464,7 +496,7 @@ pub async fn op_crypto_verify_key(
|
|||
private_key.public_key().as_ref()
|
||||
}
|
||||
KeyType::Public => &*args.key.data,
|
||||
_ => return Err(Error::InvalidKeyFormat),
|
||||
_ => return Err(CryptoError::InvalidKeyFormat),
|
||||
};
|
||||
|
||||
let public_key =
|
||||
|
@ -472,7 +504,7 @@ pub async fn op_crypto_verify_key(
|
|||
|
||||
public_key.verify(data, &args.signature).is_ok()
|
||||
}
|
||||
_ => return Err(Error::UnsupportedAlgorithm),
|
||||
_ => return Err(CryptoError::UnsupportedAlgorithm),
|
||||
};
|
||||
|
||||
Ok(verification)
|
||||
|
@ -500,31 +532,27 @@ pub struct DeriveKeyArg {
|
|||
pub async fn op_crypto_derive_bits(
|
||||
#[serde] args: DeriveKeyArg,
|
||||
#[buffer] zero_copy: Option<JsBuffer>,
|
||||
) -> Result<ToJsBuffer, Error> {
|
||||
) -> Result<ToJsBuffer, CryptoError> {
|
||||
deno_core::unsync::spawn_blocking(move || {
|
||||
let algorithm = args.algorithm;
|
||||
match algorithm {
|
||||
Algorithm::Pbkdf2 => {
|
||||
let zero_copy =
|
||||
zero_copy.ok_or_else(|| Error::Other(not_supported()))?;
|
||||
let zero_copy = zero_copy.ok_or_else(JsErrorBox::not_supported)?;
|
||||
let salt = &*zero_copy;
|
||||
// The caller must validate these cases.
|
||||
assert!(args.length > 0);
|
||||
assert!(args.length % 8 == 0);
|
||||
|
||||
let algorithm =
|
||||
match args.hash.ok_or_else(|| Error::Other(not_supported()))? {
|
||||
CryptoHash::Sha1 => pbkdf2::PBKDF2_HMAC_SHA1,
|
||||
CryptoHash::Sha256 => pbkdf2::PBKDF2_HMAC_SHA256,
|
||||
CryptoHash::Sha384 => pbkdf2::PBKDF2_HMAC_SHA384,
|
||||
CryptoHash::Sha512 => pbkdf2::PBKDF2_HMAC_SHA512,
|
||||
};
|
||||
let algorithm = match args.hash.ok_or_else(JsErrorBox::not_supported)? {
|
||||
CryptoHash::Sha1 => pbkdf2::PBKDF2_HMAC_SHA1,
|
||||
CryptoHash::Sha256 => pbkdf2::PBKDF2_HMAC_SHA256,
|
||||
CryptoHash::Sha384 => pbkdf2::PBKDF2_HMAC_SHA384,
|
||||
CryptoHash::Sha512 => pbkdf2::PBKDF2_HMAC_SHA512,
|
||||
};
|
||||
|
||||
// This will never panic. We have already checked length earlier.
|
||||
let iterations = NonZeroU32::new(
|
||||
args
|
||||
.iterations
|
||||
.ok_or_else(|| Error::Other(not_supported()))?,
|
||||
args.iterations.ok_or_else(JsErrorBox::not_supported)?,
|
||||
)
|
||||
.unwrap();
|
||||
let secret = args.key.data;
|
||||
|
@ -535,33 +563,33 @@ pub async fn op_crypto_derive_bits(
|
|||
Algorithm::Ecdh => {
|
||||
let named_curve = args
|
||||
.named_curve
|
||||
.ok_or_else(|| Error::MissingArgumentNamedCurve)?;
|
||||
.ok_or_else(|| CryptoError::MissingArgumentNamedCurve)?;
|
||||
|
||||
let public_key = args
|
||||
.public_key
|
||||
.ok_or_else(|| Error::MissingArgumentPublicKey)?;
|
||||
.ok_or_else(|| CryptoError::MissingArgumentPublicKey)?;
|
||||
|
||||
match named_curve {
|
||||
CryptoNamedCurve::P256 => {
|
||||
let secret_key = p256::SecretKey::from_pkcs8_der(&args.key.data)
|
||||
.map_err(|_| Error::DecodePrivateKey)?;
|
||||
.map_err(|_| CryptoError::DecodePrivateKey)?;
|
||||
|
||||
let public_key = match public_key.r#type {
|
||||
KeyType::Private => {
|
||||
p256::SecretKey::from_pkcs8_der(&public_key.data)
|
||||
.map_err(|_| Error::DecodePrivateKey)?
|
||||
.map_err(|_| CryptoError::DecodePrivateKey)?
|
||||
.public_key()
|
||||
}
|
||||
KeyType::Public => {
|
||||
let point = p256::EncodedPoint::from_bytes(public_key.data)
|
||||
.map_err(|_| Error::DecodePrivateKey)?;
|
||||
.map_err(|_| CryptoError::DecodePrivateKey)?;
|
||||
|
||||
let pk = p256::PublicKey::from_encoded_point(&point);
|
||||
// pk is a constant time Option.
|
||||
if pk.is_some().into() {
|
||||
pk.unwrap()
|
||||
} else {
|
||||
return Err(Error::DecodePrivateKey);
|
||||
return Err(CryptoError::DecodePrivateKey);
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
|
@ -577,24 +605,24 @@ pub async fn op_crypto_derive_bits(
|
|||
}
|
||||
CryptoNamedCurve::P384 => {
|
||||
let secret_key = p384::SecretKey::from_pkcs8_der(&args.key.data)
|
||||
.map_err(|_| Error::DecodePrivateKey)?;
|
||||
.map_err(|_| CryptoError::DecodePrivateKey)?;
|
||||
|
||||
let public_key = match public_key.r#type {
|
||||
KeyType::Private => {
|
||||
p384::SecretKey::from_pkcs8_der(&public_key.data)
|
||||
.map_err(|_| Error::DecodePrivateKey)?
|
||||
.map_err(|_| CryptoError::DecodePrivateKey)?
|
||||
.public_key()
|
||||
}
|
||||
KeyType::Public => {
|
||||
let point = p384::EncodedPoint::from_bytes(public_key.data)
|
||||
.map_err(|_| Error::DecodePrivateKey)?;
|
||||
.map_err(|_| CryptoError::DecodePrivateKey)?;
|
||||
|
||||
let pk = p384::PublicKey::from_encoded_point(&point);
|
||||
// pk is a constant time Option.
|
||||
if pk.is_some().into() {
|
||||
pk.unwrap()
|
||||
} else {
|
||||
return Err(Error::DecodePrivateKey);
|
||||
return Err(CryptoError::DecodePrivateKey);
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
|
@ -611,18 +639,16 @@ pub async fn op_crypto_derive_bits(
|
|||
}
|
||||
}
|
||||
Algorithm::Hkdf => {
|
||||
let zero_copy =
|
||||
zero_copy.ok_or_else(|| Error::Other(not_supported()))?;
|
||||
let zero_copy = zero_copy.ok_or_else(JsErrorBox::not_supported)?;
|
||||
let salt = &*zero_copy;
|
||||
let algorithm =
|
||||
match args.hash.ok_or_else(|| Error::Other(not_supported()))? {
|
||||
CryptoHash::Sha1 => hkdf::HKDF_SHA1_FOR_LEGACY_USE_ONLY,
|
||||
CryptoHash::Sha256 => hkdf::HKDF_SHA256,
|
||||
CryptoHash::Sha384 => hkdf::HKDF_SHA384,
|
||||
CryptoHash::Sha512 => hkdf::HKDF_SHA512,
|
||||
};
|
||||
let algorithm = match args.hash.ok_or_else(JsErrorBox::not_supported)? {
|
||||
CryptoHash::Sha1 => hkdf::HKDF_SHA1_FOR_LEGACY_USE_ONLY,
|
||||
CryptoHash::Sha256 => hkdf::HKDF_SHA256,
|
||||
CryptoHash::Sha384 => hkdf::HKDF_SHA384,
|
||||
CryptoHash::Sha512 => hkdf::HKDF_SHA512,
|
||||
};
|
||||
|
||||
let info = args.info.ok_or_else(|| Error::MissingArgumentInfo)?;
|
||||
let info = args.info.ok_or(CryptoError::MissingArgumentInfo)?;
|
||||
// IKM
|
||||
let secret = args.key.data;
|
||||
// L
|
||||
|
@ -633,18 +659,18 @@ pub async fn op_crypto_derive_bits(
|
|||
let info = &[&*info];
|
||||
let okm = prk
|
||||
.expand(info, HkdfOutput(length))
|
||||
.map_err(|_e| Error::HKDFLengthTooLarge)?;
|
||||
.map_err(|_e| CryptoError::HKDFLengthTooLarge)?;
|
||||
let mut r = vec![0u8; length];
|
||||
okm.fill(&mut r)?;
|
||||
Ok(r.into())
|
||||
}
|
||||
_ => Err(Error::UnsupportedAlgorithm),
|
||||
_ => Err(CryptoError::UnsupportedAlgorithm),
|
||||
}
|
||||
})
|
||||
.await?
|
||||
}
|
||||
|
||||
fn read_rsa_public_key(key_data: KeyData) -> Result<RsaPublicKey, Error> {
|
||||
fn read_rsa_public_key(key_data: KeyData) -> Result<RsaPublicKey, CryptoError> {
|
||||
let public_key = match key_data.r#type {
|
||||
KeyType::Private => {
|
||||
RsaPrivateKey::from_pkcs1_der(&key_data.data)?.to_public_key()
|
||||
|
@ -657,7 +683,9 @@ fn read_rsa_public_key(key_data: KeyData) -> Result<RsaPublicKey, Error> {
|
|||
|
||||
#[op2]
|
||||
#[string]
|
||||
pub fn op_crypto_random_uuid(state: &mut OpState) -> Result<String, Error> {
|
||||
pub fn op_crypto_random_uuid(
|
||||
state: &mut OpState,
|
||||
) -> Result<String, CryptoError> {
|
||||
let maybe_seeded_rng = state.try_borrow_mut::<StdRng>();
|
||||
let uuid = if let Some(seeded_rng) = maybe_seeded_rng {
|
||||
let mut bytes = [0u8; 16];
|
||||
|
@ -678,7 +706,7 @@ pub fn op_crypto_random_uuid(state: &mut OpState) -> Result<String, Error> {
|
|||
pub async fn op_crypto_subtle_digest(
|
||||
#[serde] algorithm: CryptoHash,
|
||||
#[buffer] data: JsBuffer,
|
||||
) -> Result<ToJsBuffer, Error> {
|
||||
) -> Result<ToJsBuffer, CryptoError> {
|
||||
let output = spawn_blocking(move || {
|
||||
digest::digest(algorithm.into(), &data)
|
||||
.as_ref()
|
||||
|
@ -702,7 +730,7 @@ pub struct WrapUnwrapKeyArg {
|
|||
pub fn op_crypto_wrap_key(
|
||||
#[serde] args: WrapUnwrapKeyArg,
|
||||
#[buffer] data: JsBuffer,
|
||||
) -> Result<ToJsBuffer, Error> {
|
||||
) -> Result<ToJsBuffer, CryptoError> {
|
||||
let algorithm = args.algorithm;
|
||||
|
||||
match algorithm {
|
||||
|
@ -710,20 +738,20 @@ pub fn op_crypto_wrap_key(
|
|||
let key = args.key.as_secret_key()?;
|
||||
|
||||
if data.len() % 8 != 0 {
|
||||
return Err(Error::DataInvalidSize);
|
||||
return Err(CryptoError::DataInvalidSize);
|
||||
}
|
||||
|
||||
let wrapped_key = match key.len() {
|
||||
16 => KekAes128::new(key.into()).wrap_vec(&data),
|
||||
24 => KekAes192::new(key.into()).wrap_vec(&data),
|
||||
32 => KekAes256::new(key.into()).wrap_vec(&data),
|
||||
_ => return Err(Error::InvalidKeyLength),
|
||||
_ => return Err(CryptoError::InvalidKeyLength),
|
||||
}
|
||||
.map_err(|_| Error::EncryptionError)?;
|
||||
.map_err(|_| CryptoError::EncryptionError)?;
|
||||
|
||||
Ok(wrapped_key.into())
|
||||
}
|
||||
_ => Err(Error::UnsupportedAlgorithm),
|
||||
_ => Err(CryptoError::UnsupportedAlgorithm),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -732,27 +760,27 @@ pub fn op_crypto_wrap_key(
|
|||
pub fn op_crypto_unwrap_key(
|
||||
#[serde] args: WrapUnwrapKeyArg,
|
||||
#[buffer] data: JsBuffer,
|
||||
) -> Result<ToJsBuffer, Error> {
|
||||
) -> Result<ToJsBuffer, CryptoError> {
|
||||
let algorithm = args.algorithm;
|
||||
match algorithm {
|
||||
Algorithm::AesKw => {
|
||||
let key = args.key.as_secret_key()?;
|
||||
|
||||
if data.len() % 8 != 0 {
|
||||
return Err(Error::DataInvalidSize);
|
||||
return Err(CryptoError::DataInvalidSize);
|
||||
}
|
||||
|
||||
let unwrapped_key = match key.len() {
|
||||
16 => KekAes128::new(key.into()).unwrap_vec(&data),
|
||||
24 => KekAes192::new(key.into()).unwrap_vec(&data),
|
||||
32 => KekAes256::new(key.into()).unwrap_vec(&data),
|
||||
_ => return Err(Error::InvalidKeyLength),
|
||||
_ => return Err(CryptoError::InvalidKeyLength),
|
||||
}
|
||||
.map_err(|_| Error::DecryptionError)?;
|
||||
.map_err(|_| CryptoError::DecryptionError)?;
|
||||
|
||||
Ok(unwrapped_key.into())
|
||||
}
|
||||
_ => Err(Error::UnsupportedAlgorithm),
|
||||
_ => Err(CryptoError::UnsupportedAlgorithm),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -60,26 +60,36 @@ pub enum RustRawKeyData {
|
|||
Public(ToJsBuffer),
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum SharedError {
|
||||
#[class(type)]
|
||||
#[error("expected valid private key")]
|
||||
ExpectedValidPrivateKey,
|
||||
#[class(type)]
|
||||
#[error("expected valid public key")]
|
||||
ExpectedValidPublicKey,
|
||||
#[class(type)]
|
||||
#[error("expected valid private EC key")]
|
||||
ExpectedValidPrivateECKey,
|
||||
#[class(type)]
|
||||
#[error("expected valid public EC key")]
|
||||
ExpectedValidPublicECKey,
|
||||
#[class(type)]
|
||||
#[error("expected private key")]
|
||||
ExpectedPrivateKey,
|
||||
#[class(type)]
|
||||
#[error("expected public key")]
|
||||
ExpectedPublicKey,
|
||||
#[class(type)]
|
||||
#[error("expected secret key")]
|
||||
ExpectedSecretKey,
|
||||
#[class("DOMExceptionOperationError")]
|
||||
#[error("failed to decode private key")]
|
||||
FailedDecodePrivateKey,
|
||||
#[class("DOMExceptionOperationError")]
|
||||
#[error("failed to decode public key")]
|
||||
FailedDecodePublicKey,
|
||||
#[class("DOMExceptionNotSupportedError")]
|
||||
#[error("unsupported format")]
|
||||
UnsupportedFormat,
|
||||
}
|
||||
|
|
|
@ -11,10 +11,12 @@ use spki::der::asn1::BitString;
|
|||
use spki::der::Decode;
|
||||
use spki::der::Encode;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum X25519Error {
|
||||
#[class("DOMExceptionOperationError")]
|
||||
#[error("Failed to export key")]
|
||||
FailedExport,
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
Der(#[from] spki::der::Error),
|
||||
}
|
||||
|
|
|
@ -12,10 +12,12 @@ use spki::der::asn1::BitString;
|
|||
use spki::der::Decode;
|
||||
use spki::der::Encode;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum X448Error {
|
||||
#[class("DOMExceptionOperationError")]
|
||||
#[error("Failed to export key")]
|
||||
FailedExport,
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
Der(#[from] spki::der::Error),
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ base64.workspace = true
|
|||
bytes.workspace = true
|
||||
data-url.workspace = true
|
||||
deno_core.workspace = true
|
||||
deno_error.workspace = true
|
||||
deno_path_util.workspace = true
|
||||
deno_permissions.workspace = true
|
||||
deno_tls.workspace = true
|
||||
|
|
|
@ -8,6 +8,7 @@ use deno_core::futures::TryStreamExt;
|
|||
use deno_core::url::Url;
|
||||
use deno_core::CancelFuture;
|
||||
use deno_core::OpState;
|
||||
use deno_error::JsErrorBox;
|
||||
use http::StatusCode;
|
||||
use http_body_util::BodyExt;
|
||||
use tokio_util::io::ReaderStream;
|
||||
|
@ -34,7 +35,7 @@ impl FetchHandler for FsFetchHandler {
|
|||
let file = tokio::fs::File::open(path).map_err(|_| ()).await?;
|
||||
let stream = ReaderStream::new(file)
|
||||
.map_ok(hyper::body::Frame::data)
|
||||
.map_err(Into::into);
|
||||
.map_err(JsErrorBox::from_err);
|
||||
let body = http_body_util::StreamBody::new(stream).boxed();
|
||||
let response = http::Response::builder()
|
||||
.status(StatusCode::OK)
|
||||
|
|
|
@ -46,6 +46,7 @@ use deno_core::OpState;
|
|||
use deno_core::RcRef;
|
||||
use deno_core::Resource;
|
||||
use deno_core::ResourceId;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_path_util::url_from_file_path;
|
||||
use deno_path_util::PathToUrlError;
|
||||
use deno_permissions::PermissionCheckError;
|
||||
|
@ -100,9 +101,8 @@ pub struct Options {
|
|||
/// For more info on what can be configured, see [`hyper_util::client::legacy::Builder`].
|
||||
pub client_builder_hook: Option<fn(HyperClientBuilder) -> HyperClientBuilder>,
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub request_builder_hook: Option<
|
||||
fn(&mut http::Request<ReqBody>) -> Result<(), deno_core::error::AnyError>,
|
||||
>,
|
||||
pub request_builder_hook:
|
||||
Option<fn(&mut http::Request<ReqBody>) -> Result<(), JsErrorBox>>,
|
||||
pub unsafely_ignore_certificate_errors: Option<Vec<String>>,
|
||||
pub client_cert_chain_and_key: TlsKeys,
|
||||
pub file_fetch_handler: Rc<dyn FetchHandler>,
|
||||
|
@ -110,9 +110,7 @@ pub struct Options {
|
|||
}
|
||||
|
||||
impl Options {
|
||||
pub fn root_cert_store(
|
||||
&self,
|
||||
) -> Result<Option<RootCertStore>, deno_core::error::AnyError> {
|
||||
pub fn root_cert_store(&self) -> Result<Option<RootCertStore>, JsErrorBox> {
|
||||
Ok(match &self.root_cert_store_provider {
|
||||
Some(provider) => Some(provider.get_or_try_init()?.clone()),
|
||||
None => None,
|
||||
|
@ -164,48 +162,71 @@ deno_core::extension!(deno_fetch,
|
|||
},
|
||||
);
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum FetchError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Resource(deno_core::error::AnyError),
|
||||
Resource(#[from] deno_core::error::ResourceError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Permission(#[from] PermissionCheckError),
|
||||
#[class(type)]
|
||||
#[error("NetworkError when attempting to fetch resource")]
|
||||
NetworkError,
|
||||
#[class(type)]
|
||||
#[error("Fetching files only supports the GET method: received {0}")]
|
||||
FsNotGet(Method),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
PathToUrl(#[from] PathToUrlError),
|
||||
#[class(type)]
|
||||
#[error("Invalid URL {0}")]
|
||||
InvalidUrl(Url),
|
||||
#[class(type)]
|
||||
#[error(transparent)]
|
||||
InvalidHeaderName(#[from] http::header::InvalidHeaderName),
|
||||
#[class(type)]
|
||||
#[error(transparent)]
|
||||
InvalidHeaderValue(#[from] http::header::InvalidHeaderValue),
|
||||
#[class(type)]
|
||||
#[error("{0:?}")]
|
||||
DataUrl(data_url::DataUrlError),
|
||||
#[class(type)]
|
||||
#[error("{0:?}")]
|
||||
Base64(data_url::forgiving_base64::InvalidBase64),
|
||||
#[class(type)]
|
||||
#[error("Blob for the given URL not found.")]
|
||||
BlobNotFound,
|
||||
#[class(type)]
|
||||
#[error("Url scheme '{0}' not supported")]
|
||||
SchemeNotSupported(String),
|
||||
#[class(type)]
|
||||
#[error("Request was cancelled")]
|
||||
RequestCanceled,
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
Http(#[from] http::Error),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
ClientCreate(#[from] HttpClientCreateError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Url(#[from] url::ParseError),
|
||||
#[class(type)]
|
||||
#[error(transparent)]
|
||||
Method(#[from] http::method::InvalidMethod),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
ClientSend(#[from] ClientSendError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
RequestBuilderHook(deno_core::error::AnyError),
|
||||
RequestBuilderHook(JsErrorBox),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Io(#[from] std::io::Error),
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
Dns(hickory_resolver::ResolveError),
|
||||
}
|
||||
|
||||
pub type CancelableResponseFuture =
|
||||
|
@ -294,9 +315,7 @@ pub fn create_client_from_options(
|
|||
#[allow(clippy::type_complexity)]
|
||||
pub struct ResourceToBodyAdapter(
|
||||
Rc<dyn Resource>,
|
||||
Option<
|
||||
Pin<Box<dyn Future<Output = Result<BufView, deno_core::error::AnyError>>>>,
|
||||
>,
|
||||
Option<Pin<Box<dyn Future<Output = Result<BufView, JsErrorBox>>>>>,
|
||||
);
|
||||
|
||||
impl ResourceToBodyAdapter {
|
||||
|
@ -312,7 +331,7 @@ unsafe impl Send for ResourceToBodyAdapter {}
|
|||
unsafe impl Sync for ResourceToBodyAdapter {}
|
||||
|
||||
impl Stream for ResourceToBodyAdapter {
|
||||
type Item = Result<Bytes, deno_core::error::AnyError>;
|
||||
type Item = Result<Bytes, JsErrorBox>;
|
||||
|
||||
fn poll_next(
|
||||
self: Pin<&mut Self>,
|
||||
|
@ -342,7 +361,7 @@ impl Stream for ResourceToBodyAdapter {
|
|||
|
||||
impl hyper::body::Body for ResourceToBodyAdapter {
|
||||
type Data = Bytes;
|
||||
type Error = deno_core::error::AnyError;
|
||||
type Error = JsErrorBox;
|
||||
|
||||
fn poll_frame(
|
||||
self: Pin<&mut Self>,
|
||||
|
@ -417,10 +436,7 @@ where
|
|||
FP: FetchPermissions + 'static,
|
||||
{
|
||||
let (client, allow_host) = if let Some(rid) = client_rid {
|
||||
let r = state
|
||||
.resource_table
|
||||
.get::<HttpClientResource>(rid)
|
||||
.map_err(FetchError::Resource)?;
|
||||
let r = state.resource_table.get::<HttpClientResource>(rid)?;
|
||||
(r.client.clone(), r.allow_host)
|
||||
} else {
|
||||
(get_or_create_client_from_state(state)?, false)
|
||||
|
@ -479,10 +495,7 @@ where
|
|||
ReqBody::full(data.to_vec().into())
|
||||
}
|
||||
(_, Some(resource)) => {
|
||||
let resource = state
|
||||
.resource_table
|
||||
.take_any(resource)
|
||||
.map_err(FetchError::Resource)?;
|
||||
let resource = state.resource_table.take_any(resource)?;
|
||||
match resource.size_hint() {
|
||||
(body_size, Some(n)) if body_size == n && body_size > 0 => {
|
||||
con_len = Some(body_size);
|
||||
|
@ -624,8 +637,7 @@ pub async fn op_fetch_send(
|
|||
let request = state
|
||||
.borrow_mut()
|
||||
.resource_table
|
||||
.take::<FetchRequestResource>(rid)
|
||||
.map_err(FetchError::Resource)?;
|
||||
.take::<FetchRequestResource>(rid)?;
|
||||
|
||||
let request = Rc::try_unwrap(request)
|
||||
.ok()
|
||||
|
@ -804,9 +816,7 @@ impl Resource for FetchResponseResource {
|
|||
// safely call `await` on it without creating a race condition.
|
||||
Some(_) => match reader.as_mut().next().await.unwrap() {
|
||||
Ok(chunk) => assert!(chunk.is_empty()),
|
||||
Err(err) => {
|
||||
break Err(deno_core::error::type_error(err.to_string()))
|
||||
}
|
||||
Err(err) => break Err(JsErrorBox::type_error(err.to_string())),
|
||||
},
|
||||
None => break Ok(BufView::empty()),
|
||||
}
|
||||
|
@ -814,7 +824,10 @@ impl Resource for FetchResponseResource {
|
|||
};
|
||||
|
||||
let cancel_handle = RcRef::map(self, |r| &r.cancel);
|
||||
fut.try_or_cancel(cancel_handle).await
|
||||
fut
|
||||
.try_or_cancel(cancel_handle)
|
||||
.await
|
||||
.map_err(JsErrorBox::from_err)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -897,9 +910,7 @@ where
|
|||
ca_certs,
|
||||
proxy: args.proxy,
|
||||
dns_resolver: if args.use_hickory_resolver {
|
||||
dns::Resolver::hickory()
|
||||
.map_err(deno_core::error::AnyError::new)
|
||||
.map_err(FetchError::Resource)?
|
||||
dns::Resolver::hickory().map_err(FetchError::Dns)?
|
||||
} else {
|
||||
dns::Resolver::default()
|
||||
},
|
||||
|
@ -963,7 +974,8 @@ impl Default for CreateHttpClientOptions {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
#[class(type)]
|
||||
pub enum HttpClientCreateError {
|
||||
#[error(transparent)]
|
||||
Tls(deno_tls::TlsError),
|
||||
|
@ -973,8 +985,9 @@ pub enum HttpClientCreateError {
|
|||
InvalidProxyUrl,
|
||||
#[error("Cannot create Http Client: either `http1` or `http2` needs to be set to true")]
|
||||
HttpVersionSelectionInvalid,
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
RootCertStore(deno_core::error::AnyError),
|
||||
RootCertStore(JsErrorBox),
|
||||
}
|
||||
|
||||
/// Create new instance of async Client. This client supports
|
||||
|
@ -1097,7 +1110,8 @@ type Connector = proxy::ProxyConnector<HttpConnector<dns::Resolver>>;
|
|||
#[allow(clippy::declare_interior_mutable_const)]
|
||||
const STAR_STAR: HeaderValue = HeaderValue::from_static("*/*");
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, deno_error::JsError)]
|
||||
#[class(type)]
|
||||
pub struct ClientSendError {
|
||||
uri: Uri,
|
||||
pub source: hyper_util::client::legacy::Error,
|
||||
|
@ -1172,7 +1186,7 @@ impl Client {
|
|||
.oneshot(req)
|
||||
.await
|
||||
.map_err(|e| ClientSendError { uri, source: e })?;
|
||||
Ok(resp.map(|b| b.map_err(|e| deno_core::anyhow::anyhow!(e)).boxed()))
|
||||
Ok(resp.map(|b| b.map_err(|e| JsErrorBox::generic(e.to_string())).boxed()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1180,10 +1194,10 @@ impl Client {
|
|||
pub enum ReqBody {
|
||||
Full(http_body_util::Full<Bytes>),
|
||||
Empty(http_body_util::Empty<Bytes>),
|
||||
Streaming(BoxBody<Bytes, deno_core::error::AnyError>),
|
||||
Streaming(BoxBody<Bytes, JsErrorBox>),
|
||||
}
|
||||
|
||||
pub type ResBody = BoxBody<Bytes, deno_core::error::AnyError>;
|
||||
pub type ResBody = BoxBody<Bytes, JsErrorBox>;
|
||||
|
||||
impl ReqBody {
|
||||
pub fn full(bytes: Bytes) -> Self {
|
||||
|
@ -1196,7 +1210,7 @@ impl ReqBody {
|
|||
|
||||
pub fn streaming<B>(body: B) -> Self
|
||||
where
|
||||
B: hyper::body::Body<Data = Bytes, Error = deno_core::error::AnyError>
|
||||
B: hyper::body::Body<Data = Bytes, Error = JsErrorBox>
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
|
@ -1207,7 +1221,7 @@ impl ReqBody {
|
|||
|
||||
impl hyper::body::Body for ReqBody {
|
||||
type Data = Bytes;
|
||||
type Error = deno_core::error::AnyError;
|
||||
type Error = JsErrorBox;
|
||||
|
||||
fn poll_frame(
|
||||
mut self: Pin<&mut Self>,
|
||||
|
|
|
@ -15,6 +15,7 @@ path = "lib.rs"
|
|||
|
||||
[dependencies]
|
||||
deno_core.workspace = true
|
||||
deno_error.workspace = true
|
||||
deno_permissions.workspace = true
|
||||
dlopen2.workspace = true
|
||||
dynasmrt = "1.2.3"
|
||||
|
|
|
@ -25,18 +25,24 @@ use crate::symbol::Symbol;
|
|||
use crate::FfiPermissions;
|
||||
use crate::ForeignFunction;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum CallError {
|
||||
#[class(type)]
|
||||
#[error(transparent)]
|
||||
IR(#[from] IRError),
|
||||
#[class(generic)]
|
||||
#[error("Nonblocking FFI call failed: {0}")]
|
||||
NonblockingCallFailure(#[source] tokio::task::JoinError),
|
||||
#[class(type)]
|
||||
#[error("Invalid FFI symbol name: '{0}'")]
|
||||
InvalidSymbol(String),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Permission(#[from] deno_permissions::PermissionCheckError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Resource(deno_core::error::AnyError),
|
||||
Resource(#[from] deno_core::error::ResourceError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Callback(#[from] super::CallbackError),
|
||||
}
|
||||
|
@ -346,10 +352,7 @@ pub fn op_ffi_call_nonblocking(
|
|||
) -> Result<impl Future<Output = Result<FfiValue, CallError>>, CallError> {
|
||||
let symbol = {
|
||||
let state = state.borrow();
|
||||
let resource = state
|
||||
.resource_table
|
||||
.get::<DynamicLibraryResource>(rid)
|
||||
.map_err(CallError::Resource)?;
|
||||
let resource = state.resource_table.get::<DynamicLibraryResource>(rid)?;
|
||||
let symbols = &resource.symbols;
|
||||
*symbols
|
||||
.get(&symbol)
|
||||
|
|
|
@ -35,14 +35,17 @@ thread_local! {
|
|||
static LOCAL_THREAD_ID: RefCell<u32> = const { RefCell::new(0) };
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum CallbackError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Resource(deno_core::error::AnyError),
|
||||
Resource(#[from] deno_core::error::ResourceError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Permission(#[from] deno_permissions::PermissionCheckError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Other(deno_core::error::AnyError),
|
||||
Other(#[from] deno_error::JsErrorBox),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -63,13 +66,8 @@ impl PtrSymbol {
|
|||
.clone()
|
||||
.into_iter()
|
||||
.map(libffi::middle::Type::try_from)
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.map_err(CallbackError::Other)?,
|
||||
def
|
||||
.result
|
||||
.clone()
|
||||
.try_into()
|
||||
.map_err(CallbackError::Other)?,
|
||||
.collect::<Result<Vec<_>, _>>()?,
|
||||
def.result.clone().try_into()?,
|
||||
);
|
||||
|
||||
Ok(Self { cif, ptr })
|
||||
|
@ -540,10 +538,8 @@ pub fn op_ffi_unsafe_callback_ref(
|
|||
#[smi] rid: ResourceId,
|
||||
) -> Result<impl Future<Output = ()>, CallbackError> {
|
||||
let state = state.borrow();
|
||||
let callback_resource = state
|
||||
.resource_table
|
||||
.get::<UnsafeCallbackResource>(rid)
|
||||
.map_err(CallbackError::Resource)?;
|
||||
let callback_resource =
|
||||
state.resource_table.get::<UnsafeCallbackResource>(rid)?;
|
||||
|
||||
Ok(async move {
|
||||
let info: &mut CallbackInfo =
|
||||
|
@ -610,10 +606,8 @@ where
|
|||
.parameters
|
||||
.into_iter()
|
||||
.map(libffi::middle::Type::try_from)
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.map_err(CallbackError::Other)?,
|
||||
libffi::middle::Type::try_from(args.result)
|
||||
.map_err(CallbackError::Other)?,
|
||||
.collect::<Result<Vec<_>, _>>()?,
|
||||
libffi::middle::Type::try_from(args.result)?,
|
||||
);
|
||||
|
||||
// SAFETY: CallbackInfo is leaked, is not null and stays valid as long as the callback exists.
|
||||
|
@ -649,10 +643,8 @@ pub fn op_ffi_unsafe_callback_close(
|
|||
// It is up to the user to know that it is safe to call the `close()` on the
|
||||
// UnsafeCallback instance.
|
||||
unsafe {
|
||||
let callback_resource = state
|
||||
.resource_table
|
||||
.take::<UnsafeCallbackResource>(rid)
|
||||
.map_err(CallbackError::Resource)?;
|
||||
let callback_resource =
|
||||
state.resource_table.take::<UnsafeCallbackResource>(rid)?;
|
||||
let info = Box::from_raw(callback_resource.info);
|
||||
let _ = v8::Global::from_raw(scope, info.callback);
|
||||
let _ = v8::Global::from_raw(scope, info.context);
|
||||
|
|
|
@ -11,6 +11,8 @@ use deno_core::v8;
|
|||
use deno_core::GarbageCollected;
|
||||
use deno_core::OpState;
|
||||
use deno_core::Resource;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_error::JsErrorClass;
|
||||
use dlopen2::raw::Library;
|
||||
use serde::Deserialize;
|
||||
use serde_value::ValueDeserializer;
|
||||
|
@ -22,20 +24,34 @@ use crate::turbocall;
|
|||
use crate::turbocall::Turbocall;
|
||||
use crate::FfiPermissions;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
deno_error::js_error_wrapper!(dlopen2::Error, JsDlopen2Error, |err| {
|
||||
match err {
|
||||
dlopen2::Error::NullCharacter(_) => "InvalidData".into(),
|
||||
dlopen2::Error::OpeningLibraryError(e) => e.get_class(),
|
||||
dlopen2::Error::SymbolGettingError(e) => e.get_class(),
|
||||
dlopen2::Error::AddrNotMatchingDll(e) => e.get_class(),
|
||||
dlopen2::Error::NullSymbol => "NotFound".into(),
|
||||
}
|
||||
});
|
||||
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum DlfcnError {
|
||||
#[class(generic)]
|
||||
#[error("Failed to register symbol {symbol}: {error}")]
|
||||
RegisterSymbol {
|
||||
symbol: String,
|
||||
#[source]
|
||||
error: dlopen2::Error,
|
||||
},
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
Dlopen(#[from] dlopen2::Error),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Permission(#[from] deno_permissions::PermissionCheckError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Other(deno_core::error::AnyError),
|
||||
Other(#[from] JsErrorBox),
|
||||
}
|
||||
|
||||
pub struct DynamicLibraryResource {
|
||||
|
@ -190,13 +206,8 @@ where
|
|||
.clone()
|
||||
.into_iter()
|
||||
.map(libffi::middle::Type::try_from)
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.map_err(DlfcnError::Other)?,
|
||||
foreign_fn
|
||||
.result
|
||||
.clone()
|
||||
.try_into()
|
||||
.map_err(DlfcnError::Other)?,
|
||||
.collect::<Result<Vec<_>, _>>()?,
|
||||
foreign_fn.result.clone().try_into()?,
|
||||
);
|
||||
|
||||
let func_key = v8::String::new(scope, &symbol_key).unwrap();
|
||||
|
@ -304,9 +315,7 @@ fn sync_fn_impl<'s>(
|
|||
unsafe { result.to_v8(scope, data.symbol.result_type.clone()) };
|
||||
rv.set(result);
|
||||
}
|
||||
Err(err) => {
|
||||
deno_core::_ops::throw_type_error(scope, err.to_string());
|
||||
}
|
||||
Err(err) => deno_core::error::throw_js_error_class(scope, &err),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,8 @@ use libffi::middle::Arg;
|
|||
|
||||
use crate::symbol::NativeType;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
#[class(type)]
|
||||
pub enum IRError {
|
||||
#[error("Invalid FFI u8 type, expected boolean")]
|
||||
InvalidU8ExpectedBoolean,
|
||||
|
|
|
@ -11,7 +11,8 @@ use deno_core::OpState;
|
|||
|
||||
use crate::FfiPermissions;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
#[class(type)]
|
||||
pub enum ReprError {
|
||||
#[error("Invalid pointer to offset, pointer is null")]
|
||||
InvalidOffset,
|
||||
|
@ -47,6 +48,7 @@ pub enum ReprError {
|
|||
InvalidF64,
|
||||
#[error("Invalid pointer pointer, pointer is null")]
|
||||
InvalidPointer,
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Permission(#[from] deno_permissions::PermissionCheckError),
|
||||
}
|
||||
|
|
|
@ -10,16 +10,20 @@ use deno_core::ResourceId;
|
|||
use crate::dlfcn::DynamicLibraryResource;
|
||||
use crate::symbol::NativeType;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum StaticError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Dlfcn(super::DlfcnError),
|
||||
#[class(type)]
|
||||
#[error("Invalid FFI static type 'void'")]
|
||||
InvalidTypeVoid,
|
||||
#[class(type)]
|
||||
#[error("Invalid FFI static type 'struct'")]
|
||||
InvalidTypeStruct,
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Resource(deno_core::error::AnyError),
|
||||
Resource(#[from] deno_core::error::ResourceError),
|
||||
}
|
||||
|
||||
#[op2]
|
||||
|
@ -31,10 +35,7 @@ pub fn op_ffi_get_static<'scope>(
|
|||
#[serde] static_type: NativeType,
|
||||
optional: bool,
|
||||
) -> Result<v8::Local<'scope, v8::Value>, StaticError> {
|
||||
let resource = state
|
||||
.resource_table
|
||||
.get::<DynamicLibraryResource>(rid)
|
||||
.map_err(StaticError::Resource)?;
|
||||
let resource = state.resource_table.get::<DynamicLibraryResource>(rid)?;
|
||||
|
||||
let data_ptr = match resource.get_static(name) {
|
||||
Ok(data_ptr) => data_ptr,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use deno_core::error::type_error;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_error::JsErrorBox;
|
||||
|
||||
/// Defines the accepted types that can be used as
|
||||
/// parameters and return values in FFI.
|
||||
|
@ -29,7 +28,7 @@ pub enum NativeType {
|
|||
}
|
||||
|
||||
impl TryFrom<NativeType> for libffi::middle::Type {
|
||||
type Error = AnyError;
|
||||
type Error = JsErrorBox;
|
||||
|
||||
fn try_from(native_type: NativeType) -> Result<Self, Self::Error> {
|
||||
Ok(match native_type {
|
||||
|
@ -56,7 +55,9 @@ impl TryFrom<NativeType> for libffi::middle::Type {
|
|||
.map(|field| field.clone().try_into())
|
||||
.collect::<Result<Vec<_>, _>>()?,
|
||||
false => {
|
||||
return Err(type_error("Struct must have at least one field"))
|
||||
return Err(JsErrorBox::type_error(
|
||||
"Struct must have at least one field",
|
||||
))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ async-trait.workspace = true
|
|||
base32.workspace = true
|
||||
boxed_error.workspace = true
|
||||
deno_core.workspace = true
|
||||
deno_error.workspace = true
|
||||
deno_io.workspace = true
|
||||
deno_path_util.workspace = true
|
||||
deno_permissions.workspace = true
|
||||
|
|
|
@ -12,6 +12,7 @@ use std::path::StripPrefixError;
|
|||
use std::rc::Rc;
|
||||
|
||||
use boxed_error::Boxed;
|
||||
use deno_core::error::ResourceError;
|
||||
use deno_core::op2;
|
||||
use deno_core::CancelFuture;
|
||||
use deno_core::CancelHandle;
|
||||
|
@ -20,6 +21,7 @@ use deno_core::JsBuffer;
|
|||
use deno_core::OpState;
|
||||
use deno_core::ResourceId;
|
||||
use deno_core::ToJsBuffer;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_io::fs::FileResource;
|
||||
use deno_io::fs::FsError;
|
||||
use deno_io::fs::FsStat;
|
||||
|
@ -36,34 +38,46 @@ use crate::interface::FsFileType;
|
|||
use crate::FsPermissions;
|
||||
use crate::OpenOptions;
|
||||
|
||||
#[derive(Debug, Boxed)]
|
||||
#[derive(Debug, Boxed, deno_error::JsError)]
|
||||
pub struct FsOpsError(pub Box<FsOpsErrorKind>);
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum FsOpsErrorKind {
|
||||
#[class(inherit)]
|
||||
#[error("{0}")]
|
||||
Io(#[source] std::io::Error),
|
||||
#[class(inherit)]
|
||||
#[error("{0}")]
|
||||
OperationError(#[source] OperationError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Permission(#[from] PermissionCheckError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Resource(deno_core::error::AnyError),
|
||||
Resource(#[from] ResourceError),
|
||||
#[class("InvalidData")]
|
||||
#[error("File name or path {0:?} is not valid UTF-8")]
|
||||
InvalidUtf8(std::ffi::OsString),
|
||||
#[class(generic)]
|
||||
#[error("{0}")]
|
||||
StripPrefix(#[from] StripPrefixError),
|
||||
#[class(inherit)]
|
||||
#[error("{0}")]
|
||||
Canceled(#[from] deno_core::Canceled),
|
||||
#[class(type)]
|
||||
#[error("Invalid seek mode: {0}")]
|
||||
InvalidSeekMode(i32),
|
||||
#[class(generic)]
|
||||
#[error("Invalid control character in prefix or suffix: {0:?}")]
|
||||
InvalidControlCharacter(String),
|
||||
#[class(generic)]
|
||||
#[error("Invalid character in prefix or suffix: {0:?}")]
|
||||
InvalidCharacter(String),
|
||||
#[cfg(windows)]
|
||||
#[class(generic)]
|
||||
#[error("Invalid trailing character in suffix")]
|
||||
InvalidTrailingCharacter,
|
||||
#[class("NotCapable")]
|
||||
#[error("Requires {err} access to {path}, {}", print_not_capable_info(*.standalone, .err))]
|
||||
NotCapableAccess {
|
||||
// NotCapable
|
||||
|
@ -71,21 +85,21 @@ pub enum FsOpsErrorKind {
|
|||
err: &'static str,
|
||||
path: String,
|
||||
},
|
||||
#[class("NotCapable")]
|
||||
#[error("permission denied: {0}")]
|
||||
NotCapable(&'static str), // NotCapable
|
||||
NotCapable(&'static str),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Other(deno_core::error::AnyError),
|
||||
Other(JsErrorBox),
|
||||
}
|
||||
|
||||
impl From<FsError> for FsOpsError {
|
||||
fn from(err: FsError) -> Self {
|
||||
match err {
|
||||
FsError::Io(err) => FsOpsErrorKind::Io(err),
|
||||
FsError::FileBusy => {
|
||||
FsOpsErrorKind::Other(deno_core::error::resource_unavailable())
|
||||
}
|
||||
FsError::FileBusy => FsOpsErrorKind::Resource(ResourceError::Unavailable),
|
||||
FsError::NotSupported => {
|
||||
FsOpsErrorKind::Other(deno_core::error::not_supported())
|
||||
FsOpsErrorKind::Other(JsErrorBox::not_supported())
|
||||
}
|
||||
FsError::NotCapable(err) => FsOpsErrorKind::NotCapable(err),
|
||||
}
|
||||
|
@ -1666,10 +1680,12 @@ pub async fn op_fs_futime_async(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, deno_error::JsError)]
|
||||
#[class(inherit)]
|
||||
pub struct OperationError {
|
||||
operation: &'static str,
|
||||
kind: OperationErrorKind,
|
||||
#[inherit]
|
||||
pub err: FsError,
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ brotli.workspace = true
|
|||
bytes.workspace = true
|
||||
cache_control.workspace = true
|
||||
deno_core.workspace = true
|
||||
deno_error.workspace = true
|
||||
deno_net.workspace = true
|
||||
deno_websocket.workspace = true
|
||||
flate2.workspace = true
|
||||
|
|
|
@ -146,24 +146,44 @@ macro_rules! clone_external {
|
|||
}};
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum HttpNextError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Resource(deno_core::error::AnyError),
|
||||
Resource(#[from] deno_core::error::ResourceError),
|
||||
#[class(inherit)]
|
||||
#[error("{0}")]
|
||||
Io(#[from] io::Error),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
WebSocketUpgrade(crate::websocket_upgrade::WebSocketUpgradeError),
|
||||
#[class("Http")]
|
||||
#[error("{0}")]
|
||||
Hyper(#[from] hyper::Error),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
JoinError(#[from] tokio::task::JoinError),
|
||||
JoinError(
|
||||
#[from]
|
||||
#[inherit]
|
||||
tokio::task::JoinError,
|
||||
),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Canceled(#[from] deno_core::Canceled),
|
||||
#[error(transparent)]
|
||||
HttpPropertyExtractor(deno_core::error::AnyError),
|
||||
Canceled(
|
||||
#[from]
|
||||
#[inherit]
|
||||
deno_core::Canceled,
|
||||
),
|
||||
#[class(generic)]
|
||||
#[error(transparent)]
|
||||
UpgradeUnavailable(#[from] crate::service::UpgradeUnavailableError),
|
||||
#[class(inherit)]
|
||||
#[error("{0}")]
|
||||
Other(
|
||||
#[from]
|
||||
#[inherit]
|
||||
deno_error::JsErrorBox,
|
||||
),
|
||||
}
|
||||
|
||||
#[op2(fast)]
|
||||
|
@ -747,15 +767,9 @@ pub async fn op_http_set_response_body_resource(
|
|||
let resource = {
|
||||
let mut state = state.borrow_mut();
|
||||
if auto_close {
|
||||
state
|
||||
.resource_table
|
||||
.take_any(stream_rid)
|
||||
.map_err(HttpNextError::Resource)?
|
||||
state.resource_table.take_any(stream_rid)?
|
||||
} else {
|
||||
state
|
||||
.resource_table
|
||||
.get_any(stream_rid)
|
||||
.map_err(HttpNextError::Resource)?
|
||||
state.resource_table.get_any(stream_rid)?
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1063,8 +1077,7 @@ where
|
|||
HTTP: HttpPropertyExtractor,
|
||||
{
|
||||
let listener =
|
||||
HTTP::get_listener_for_rid(&mut state.borrow_mut(), listener_rid)
|
||||
.map_err(HttpNextError::Resource)?;
|
||||
HTTP::get_listener_for_rid(&mut state.borrow_mut(), listener_rid)?;
|
||||
|
||||
let listen_properties = HTTP::listen_properties_from_listener(&listener)?;
|
||||
|
||||
|
@ -1084,8 +1097,7 @@ where
|
|||
loop {
|
||||
let conn = HTTP::accept_connection_from_listener(&listener)
|
||||
.try_or_cancel(listen_cancel_clone.clone())
|
||||
.await
|
||||
.map_err(HttpNextError::HttpPropertyExtractor)?;
|
||||
.await?;
|
||||
serve_http_on::<HTTP>(
|
||||
conn,
|
||||
&listen_properties_clone,
|
||||
|
@ -1120,8 +1132,7 @@ where
|
|||
HTTP: HttpPropertyExtractor,
|
||||
{
|
||||
let connection =
|
||||
HTTP::get_connection_for_rid(&mut state.borrow_mut(), connection_rid)
|
||||
.map_err(HttpNextError::Resource)?;
|
||||
HTTP::get_connection_for_rid(&mut state.borrow_mut(), connection_rid)?;
|
||||
|
||||
let listen_properties = HTTP::listen_properties_from_connection(&connection)?;
|
||||
|
||||
|
@ -1190,8 +1201,7 @@ pub async fn op_http_wait(
|
|||
let join_handle = state
|
||||
.borrow_mut()
|
||||
.resource_table
|
||||
.get::<HttpJoinHandle>(rid)
|
||||
.map_err(HttpNextError::Resource)?;
|
||||
.get::<HttpJoinHandle>(rid)?;
|
||||
|
||||
let cancel = join_handle.listen_cancel_handle();
|
||||
let next = async {
|
||||
|
@ -1236,7 +1246,7 @@ pub fn op_http_cancel(
|
|||
state: &mut OpState,
|
||||
#[smi] rid: ResourceId,
|
||||
graceful: bool,
|
||||
) -> Result<(), deno_core::error::AnyError> {
|
||||
) -> Result<(), deno_core::error::ResourceError> {
|
||||
let join_handle = state.resource_table.get::<HttpJoinHandle>(rid)?;
|
||||
|
||||
if graceful {
|
||||
|
@ -1260,8 +1270,7 @@ pub async fn op_http_close(
|
|||
let join_handle = state
|
||||
.borrow_mut()
|
||||
.resource_table
|
||||
.take::<HttpJoinHandle>(rid)
|
||||
.map_err(HttpNextError::Resource)?;
|
||||
.take::<HttpJoinHandle>(rid)?;
|
||||
|
||||
if graceful {
|
||||
http_general_trace!("graceful shutdown");
|
||||
|
@ -1390,11 +1399,8 @@ pub async fn op_raw_write_vectored(
|
|||
#[buffer] buf1: JsBuffer,
|
||||
#[buffer] buf2: JsBuffer,
|
||||
) -> Result<usize, HttpNextError> {
|
||||
let resource: Rc<UpgradeStream> = state
|
||||
.borrow()
|
||||
.resource_table
|
||||
.get::<UpgradeStream>(rid)
|
||||
.map_err(HttpNextError::Resource)?;
|
||||
let resource: Rc<UpgradeStream> =
|
||||
state.borrow().resource_table.get::<UpgradeStream>(rid)?;
|
||||
let nwritten = resource.write_vectored(&buf1, &buf2).await?;
|
||||
Ok(nwritten)
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ use deno_core::RcRef;
|
|||
use deno_core::Resource;
|
||||
use deno_core::ResourceId;
|
||||
use deno_core::StringOrBuffer;
|
||||
use deno_error::JsErrorBox;
|
||||
use deno_net::raw::NetworkStream;
|
||||
use deno_websocket::ws_create_server_stream;
|
||||
use flate2::write::GzEncoder;
|
||||
|
@ -165,36 +166,50 @@ deno_core::extension!(
|
|||
}
|
||||
);
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[derive(Debug, thiserror::Error, deno_error::JsError)]
|
||||
pub enum HttpError {
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Resource(deno_core::error::AnyError),
|
||||
Resource(#[from] deno_core::error::ResourceError),
|
||||
#[class(inherit)]
|
||||
#[error(transparent)]
|
||||
Canceled(#[from] deno_core::Canceled),
|
||||
#[class("Http")]
|
||||
#[error("{0}")]
|
||||
HyperV014(#[source] Arc<hyper_v014::Error>),
|
||||
#[class(generic)]
|
||||
#[error("{0}")]
|
||||
InvalidHeaderName(#[from] hyper_v014::header::InvalidHeaderName),
|
||||
#[class(generic)]
|
||||
#[error("{0}")]
|
||||
InvalidHeaderValue(#[from] hyper_v014::header::InvalidHeaderValue),
|
||||
#[class(generic)]
|
||||
#[error("{0}")]
|
||||
Http(#[from] hyper_v014::http::Error),
|
||||
#[class("Http")]
|
||||
#[error("response headers already sent")]
|
||||
ResponseHeadersAlreadySent,
|
||||
#[class("Http")]
|
||||
#[error("connection closed while sending response")]
|
||||
ConnectionClosedWhileSendingResponse,
|
||||
#[class("Http")]
|
||||
#[error("already in use")]
|
||||
AlreadyInUse,
|
||||
#[class(inherit)]
|
||||
#[error("{0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
#[class("Http")]
|
||||
#[error("no response headers")]
|
||||
NoResponseHeaders,
|
||||
#[class("Http")]
|
||||
#[error("response already completed")]
|
||||
ResponseAlreadyCompleted,
|
||||
#[class("Http")]
|
||||
#[error("cannot upgrade because request body was used")]
|
||||
UpgradeBodyUsed,
|
||||
#[class("Http")]
|
||||
#[error(transparent)]
|
||||
Other(deno_core::error::AnyError),
|
||||
Other(#[from] JsErrorBox),
|
||||
}
|
||||
|
||||
pub enum HttpSocketAddr {
|
||||
|
@ -486,7 +501,9 @@ impl Resource for HttpStreamReadResource {
|
|||
Some(_) => match body.as_mut().next().await.unwrap() {
|
||||
Ok(chunk) => assert!(chunk.is_empty()),
|
||||
Err(err) => {
|
||||
break Err(HttpError::HyperV014(Arc::new(err)).into())
|
||||
break Err(JsErrorBox::from_err(HttpError::HyperV014(
|
||||
Arc::new(err),
|
||||
)))
|
||||
}
|
||||
},
|
||||
None => break Ok(BufView::empty()),
|
||||
|
@ -610,11 +627,7 @@ async fn op_http_accept(
|
|||
state: Rc<RefCell<OpState>>,
|
||||
#[smi] rid: ResourceId,
|
||||
) -> Result<Option<NextRequestResponse>, HttpError> {
|
||||
let conn = state
|
||||
.borrow()
|
||||
.resource_table
|
||||
.get::<HttpConnResource>(rid)
|
||||
.map_err(HttpError::Resource)?;
|
||||
let conn = state.borrow().resource_table.get::<HttpConnResource>(rid)?;
|
||||
|
||||
match conn.accept().await {
|
||||
Ok(Some((read_stream, write_stream, method, url))) => {
|
||||
|
@ -729,8 +742,7 @@ async fn op_http_write_headers(
|
|||
let stream = state
|
||||
.borrow_mut()
|
||||
.resource_table
|
||||
.get::<HttpStreamWriteResource>(rid)
|
||||
.map_err(HttpError::Resource)?;
|
||||
.get::<HttpStreamWriteResource>(rid)?;
|
||||
|
||||
// Track supported encoding
|
||||
let encoding = stream.accept_encoding;
|
||||
|
@ -795,10 +807,7 @@ fn op_http_headers(
|
|||
state: &mut OpState,
|
||||
#[smi] rid: u32,
|
||||
) -> Result<Vec<(ByteString, ByteString)>, HttpError> {
|
||||
let stream = state
|
||||
.resource_table
|
||||
.get::<HttpStreamReadResource>(rid)
|
||||
.map_err(HttpError::Resource)?;
|
||||
let stream = state.resource_table.get::<HttpStreamReadResource>(rid)?;
|
||||
let rd = RcRef::map(&stream, |r| &r.rd)
|
||||
.try_borrow()
|
||||
.ok_or(HttpError::AlreadyInUse)?;
|
||||
|
@ -954,14 +963,9 @@ async fn op_http_write_resource(
|
|||
let http_stream = state
|
||||
.borrow()
|
||||
.resource_table
|
||||
.get::<HttpStreamWriteResource>(rid)
|
||||
.map_err(HttpError::Resource)?;
|
||||
.get::<HttpStreamWriteResource>(rid)?;
|
||||
let mut wr = RcRef::map(&http_stream, |r| &r.wr).borrow_mut().await;
|
||||
let resource = state
|
||||
.borrow()
|
||||
.resource_table
|
||||
.get_any(stream)
|
||||
.map_err(HttpError::Resource)?;
|
||||
let resource = state.borrow().resource_table.get_any(stream)?;
|
||||
loop {
|
||||
match *wr {
|
||||
HttpResponseWriter::Headers(_) => {
|
||||
|
@ -973,11 +977,7 @@ async fn op_http_write_resource(
|
|||
_ => {}
|
||||
};
|
||||
|
||||
let view = resource
|
||||
.clone()
|
||||
.read(64 * 1024)
|
||||
.await
|
||||
.map_err(HttpError::Other)?; // 64KB
|
||||
let view = resource.clone().read(64 * 1024).await?; // 64KB
|
||||
if view.is_empty() {
|
||||
break;
|
||||
}
|
||||
|
@ -1022,8 +1022,7 @@ async fn op_http_write(
|
|||
let stream = state
|
||||
.borrow()
|
||||
.resource_table
|
||||
.get::<HttpStreamWriteResource>(rid)
|
||||
.map_err(HttpError::Resource)?;
|
||||
.get::<HttpStreamWriteResource>(rid)?;
|
||||
let mut wr = RcRef::map(&stream, |r| &r.wr).borrow_mut().await;
|
||||
|
||||
match &mut *wr {
|
||||
|
@ -1075,8 +1074,7 @@ async fn op_http_shutdown(
|
|||
let stream = state
|
||||
.borrow()
|
||||
.resource_table
|
||||
.get::<HttpStreamWriteResource>(rid)
|
||||
.map_err(HttpError::Resource)?;
|
||||
.get::<HttpStreamWriteResource>(rid)?;
|
||||
let mut wr = RcRef::map(&stream, |r| &r.wr).borrow_mut().await;
|
||||
let wr = take(&mut *wr);
|
||||
match wr {
|
||||
|
@ -1122,8 +1120,7 @@ async fn op_http_upgrade_websocket(
|
|||
let stream = state
|
||||
.borrow_mut()
|
||||
.resource_table
|
||||
.get::<HttpStreamReadResource>(rid)
|
||||
.map_err(HttpError::Resource)?;
|
||||
.get::<HttpStreamReadResource>(rid)?;
|
||||
let mut rd = RcRef::map(&stream, |r| &r.rd).borrow_mut().await;
|
||||
|
||||
let request = match &mut *rd {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue