summaryrefslogtreecommitdiff
path: root/runtime/ops/web_worker
diff options
context:
space:
mode:
authorhaturau <135221985+haturatu@users.noreply.github.com>2024-11-20 01:20:47 +0900
committerGitHub <noreply@github.com>2024-11-20 01:20:47 +0900
commit85719a67e59c7aa45bead26e4942d7df8b1b42d4 (patch)
treeface0aecaac53e93ce2f23b53c48859bcf1a36ec /runtime/ops/web_worker
parent67697bc2e4a62a9670699fd18ad0dd8efc5bd955 (diff)
parent186b52731c6bb326c4d32905c5e732d082e83465 (diff)
Merge branch 'denoland:main' into main
Diffstat (limited to 'runtime/ops/web_worker')
-rw-r--r--runtime/ops/web_worker/sync_fetch.rs95
1 files changed, 57 insertions, 38 deletions
diff --git a/runtime/ops/web_worker/sync_fetch.rs b/runtime/ops/web_worker/sync_fetch.rs
index cdb151a86..d1f133d3d 100644
--- a/runtime/ops/web_worker/sync_fetch.rs
+++ b/runtime/ops/web_worker/sync_fetch.rs
@@ -4,15 +4,13 @@ use std::sync::Arc;
use crate::web_worker::WebWorkerInternalHandle;
use crate::web_worker::WebWorkerType;
-use deno_core::error::type_error;
-use deno_core::error::AnyError;
use deno_core::futures::StreamExt;
use deno_core::op2;
use deno_core::url::Url;
use deno_core::OpState;
use deno_fetch::data_url::DataUrl;
+use deno_fetch::FetchError;
use deno_web::BlobStore;
-use deno_websocket::DomExceptionNetworkError;
use http_body_util::BodyExt;
use hyper::body::Bytes;
use serde::Deserialize;
@@ -27,6 +25,32 @@ fn mime_type_essence(mime_type: &str) -> String {
essence.trim().to_ascii_lowercase()
}
+#[derive(Debug, thiserror::Error)]
+pub enum SyncFetchError {
+ #[error("Blob URLs are not supported in this context.")]
+ BlobUrlsNotSupportedInContext,
+ #[error("{0}")]
+ Io(#[from] std::io::Error),
+ #[error("Invalid script URL")]
+ InvalidScriptUrl,
+ #[error("http status error: {0}")]
+ InvalidStatusCode(http::StatusCode),
+ #[error("Classic scripts with scheme {0}: are not supported in workers")]
+ ClassicScriptSchemeUnsupportedInWorkers(String),
+ #[error("{0}")]
+ InvalidUri(#[from] http::uri::InvalidUri),
+ #[error("Invalid MIME type {0:?}.")]
+ InvalidMimeType(String),
+ #[error("Missing MIME type.")]
+ MissingMimeType,
+ #[error(transparent)]
+ Fetch(#[from] FetchError),
+ #[error(transparent)]
+ Join(#[from] tokio::task::JoinError),
+ #[error(transparent)]
+ Other(deno_core::error::AnyError),
+}
+
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SyncFetchScript {
@@ -40,21 +64,22 @@ pub fn op_worker_sync_fetch(
state: &mut OpState,
#[serde] scripts: Vec<String>,
loose_mime_checks: bool,
-) -> Result<Vec<SyncFetchScript>, AnyError> {
+) -> Result<Vec<SyncFetchScript>, SyncFetchError> {
let handle = state.borrow::<WebWorkerInternalHandle>().clone();
assert_eq!(handle.worker_type, WebWorkerType::Classic);
// it's not safe to share a client across tokio runtimes, so create a fresh one
// https://github.com/seanmonstar/reqwest/issues/1148#issuecomment-910868788
let options = state.borrow::<deno_fetch::Options>().clone();
- let client = deno_fetch::create_client_from_options(&options)?;
+ let client = deno_fetch::create_client_from_options(&options)
+ .map_err(FetchError::ClientCreate)?;
// TODO(andreubotella) It's not good to throw an exception related to blob
// URLs when none of the script URLs use the blob scheme.
// Also, in which contexts are blob URLs not supported?
let blob_store = state
.try_borrow::<Arc<BlobStore>>()
- .ok_or_else(|| type_error("Blob URLs are not supported in this context."))?
+ .ok_or(SyncFetchError::BlobUrlsNotSupportedInContext)?
.clone();
// TODO(andreubotella): make the below thread into a resource that can be
@@ -74,7 +99,7 @@ pub fn op_worker_sync_fetch(
let blob_store = blob_store.clone();
deno_core::unsync::spawn(async move {
let script_url = Url::parse(&script)
- .map_err(|_| type_error("Invalid script URL"))?;
+ .map_err(|_| SyncFetchError::InvalidScriptUrl)?;
let mut loose_mime_checks = loose_mime_checks;
let (body, mime_type, res_url) = match script_url.scheme() {
@@ -86,15 +111,13 @@ pub fn op_worker_sync_fetch(
);
*req.uri_mut() = script_url.as_str().parse()?;
- let resp = client.send(req).await?;
+ let resp =
+ client.send(req).await.map_err(FetchError::ClientSend)?;
if resp.status().is_client_error()
|| resp.status().is_server_error()
{
- return Err(type_error(format!(
- "http status error: {}",
- resp.status()
- )));
+ return Err(SyncFetchError::InvalidStatusCode(resp.status()));
}
// TODO(andreubotella) Properly run fetch's "extract a MIME type".
@@ -107,42 +130,45 @@ pub fn op_worker_sync_fetch(
// Always check the MIME type with HTTP(S).
loose_mime_checks = false;
- let body = resp.collect().await?.to_bytes();
+ let body = resp
+ .collect()
+ .await
+ .map_err(SyncFetchError::Other)?
+ .to_bytes();
(body, mime_type, script)
}
"data" => {
- let data_url = DataUrl::process(&script)
- .map_err(|e| type_error(format!("{e:?}")))?;
+ let data_url =
+ DataUrl::process(&script).map_err(FetchError::DataUrl)?;
let mime_type = {
let mime = data_url.mime_type();
format!("{}/{}", mime.type_, mime.subtype)
};
- let (body, _) = data_url
- .decode_to_vec()
- .map_err(|e| type_error(format!("{e:?}")))?;
+ let (body, _) =
+ data_url.decode_to_vec().map_err(FetchError::Base64)?;
(Bytes::from(body), Some(mime_type), script)
}
"blob" => {
- let blob =
- blob_store.get_object_url(script_url).ok_or_else(|| {
- type_error("Blob for the given URL not found.")
- })?;
+ let blob = blob_store
+ .get_object_url(script_url)
+ .ok_or(FetchError::BlobNotFound)?;
let mime_type = mime_type_essence(&blob.media_type);
- let body = blob.read_all().await?;
+ let body = blob.read_all().await;
(Bytes::from(body), Some(mime_type), script)
}
_ => {
- return Err(type_error(format!(
- "Classic scripts with scheme {}: are not supported in workers.",
- script_url.scheme()
- )))
+ return Err(
+ SyncFetchError::ClassicScriptSchemeUnsupportedInWorkers(
+ script_url.scheme().to_string(),
+ ),
+ )
}
};
@@ -151,18 +177,11 @@ pub fn op_worker_sync_fetch(
match mime_type.as_deref() {
Some("application/javascript" | "text/javascript") => {}
Some(mime_type) => {
- return Err(
- DomExceptionNetworkError {
- msg: format!("Invalid MIME type {mime_type:?}."),
- }
- .into(),
- )
- }
- None => {
- return Err(
- DomExceptionNetworkError::new("Missing MIME type.").into(),
- )
+ return Err(SyncFetchError::InvalidMimeType(
+ mime_type.to_string(),
+ ))
}
+ None => return Err(SyncFetchError::MissingMimeType),
}
}