summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/runtime.rs2
-rw-r--r--serde_v8/de.rs21
-rw-r--r--serde_v8/error.rs145
-rw-r--r--serde_v8/magic/bigint.rs3
-rw-r--r--serde_v8/magic/bytestring.rs3
-rw-r--r--serde_v8/magic/detached_buffer.rs7
-rw-r--r--serde_v8/magic/external_pointer.rs4
-rw-r--r--serde_v8/magic/string_or_buffer.rs3
-rw-r--r--serde_v8/magic/u16string.rs3
-rw-r--r--serde_v8/magic/v8slice.rs4
-rw-r--r--serde_v8/tests/de.rs2
11 files changed, 152 insertions, 45 deletions
diff --git a/core/runtime.rs b/core/runtime.rs
index 3723a917a..9ead489af 100644
--- a/core/runtime.rs
+++ b/core/runtime.rs
@@ -4385,7 +4385,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", {
let sum = Deno.core.ops.op_sum_take(w32.subarray(0, 2));
return false;
} catch(e) {
- return e.message.includes('invalid type, expected: detachable');
+ return e.message.includes('invalid type; expected: detachable');
}
});
if (!assertWasmThrow()) {
diff --git a/serde_v8/de.rs b/serde_v8/de.rs
index d593ffbc5..edb1263eb 100644
--- a/serde_v8/de.rs
+++ b/serde_v8/de.rs
@@ -4,6 +4,7 @@ use serde::de::Visitor;
use serde::de::{self};
use serde::Deserialize;
+use crate::error::value_to_type_str;
use crate::error::Error;
use crate::error::Result;
use crate::keys::v8_struct_key;
@@ -84,7 +85,7 @@ macro_rules! deserialize_signed {
} else if let Some(x) = self.input.to_big_int(self.scope) {
x.i64_value().0 as $t
} else {
- return Err(Error::ExpectedInteger);
+ return Err(Error::ExpectedInteger(value_to_type_str(self.input)));
},
)
}
@@ -107,7 +108,7 @@ macro_rules! deserialize_unsigned {
} else if let Some(x) = self.input.to_big_int(self.scope) {
x.u64_value().0 as $t
} else {
- return Err(Error::ExpectedInteger);
+ return Err(Error::ExpectedInteger(value_to_type_str(self.input)));
},
)
}
@@ -188,7 +189,7 @@ impl<'de, 'a, 'b, 's, 'x> de::Deserializer<'de>
} else if let Some(x) = self.input.to_big_int(self.scope) {
bigint_to_f64(x)
} else {
- return Err(Error::ExpectedNumber);
+ return Err(Error::ExpectedNumber(value_to_type_str(self.input)));
},
)
}
@@ -216,7 +217,7 @@ impl<'de, 'a, 'b, 's, 'x> de::Deserializer<'de>
let string = to_utf8(v8_string, self.scope);
visitor.visit_string(string)
} else {
- Err(Error::ExpectedString)
+ Err(Error::ExpectedString(value_to_type_str(self.input)))
}
}
@@ -268,7 +269,7 @@ impl<'de, 'a, 'b, 's, 'x> de::Deserializer<'de>
V: Visitor<'de>,
{
let arr = v8::Local::<v8::Array>::try_from(self.input)
- .map_err(|_| Error::ExpectedArray)?;
+ .map_err(|_| Error::ExpectedArray(value_to_type_str(self.input)))?;
visitor.visit_seq(SeqAccess::new(arr.into(), self.scope, 0..arr.length()))
}
@@ -308,7 +309,7 @@ impl<'de, 'a, 'b, 's, 'x> de::Deserializer<'de>
{
// Assume object, then get_own_property_names
let obj = v8::Local::<v8::Object>::try_from(self.input)
- .map_err(|_| Error::ExpectedObject)?;
+ .map_err(|_| Error::ExpectedObject(value_to_type_str(self.input)))?;
if v8::Local::<v8::Map>::try_from(self.input).is_ok() {
let pairs_array = v8::Local::<v8::Map>::try_from(self.input)
@@ -363,7 +364,7 @@ impl<'de, 'a, 'b, 's, 'x> de::Deserializer<'de>
_ => {
// Regular struct
let obj = v8::Local::<v8::Object>::try_from(self.input)
- .or(Err(Error::ExpectedObject))?;
+ .map_err(|_| Error::ExpectedObject(value_to_type_str(self.input)))?;
// Fields names are a hint and must be inferred when not provided
if fields.is_empty() {
@@ -409,7 +410,8 @@ impl<'de, 'a, 'b, 's, 'x> de::Deserializer<'de>
let tag = {
let prop_names =
obj.get_own_property_names(self.scope, Default::default());
- let prop_names = prop_names.ok_or(Error::ExpectedEnum)?;
+ let prop_names = prop_names
+ .ok_or_else(|| Error::ExpectedEnum(value_to_type_str(self.input)))?;
let prop_names_len = prop_names.length();
if prop_names_len != 1 {
return Err(Error::LengthMismatch(prop_names_len as usize, 1));
@@ -424,8 +426,7 @@ impl<'de, 'a, 'b, 's, 'x> de::Deserializer<'de>
payload,
})
} else {
- // TODO: improve error
- Err(Error::ExpectedEnum)
+ Err(Error::ExpectedEnum(value_to_type_str(self.input)))
}
}
diff --git a/serde_v8/error.rs b/serde_v8/error.rs
index 94ac3c0a5..aa2d92bf8 100644
--- a/serde_v8/error.rs
+++ b/serde_v8/error.rs
@@ -9,30 +9,41 @@ pub enum Error {
#[error("{0}")]
Message(String),
- #[error("serde_v8 error: invalid type, expected: boolean")]
- ExpectedBoolean,
- #[error("serde_v8 error: invalid type, expected: integer")]
- ExpectedInteger,
- #[error("serde_v8 error: invalid type, expected: number")]
- ExpectedNumber,
- #[error("serde_v8 error: invalid type, expected: string")]
- ExpectedString,
- #[error("serde_v8 error: invalid type, expected: array")]
- ExpectedArray,
- #[error("serde_v8 error: invalid type, expected: map")]
- ExpectedMap,
- #[error("serde_v8 error: invalid type, expected: enum")]
- ExpectedEnum,
- #[error("serde_v8 error: invalid type, expected: object")]
- ExpectedObject,
- #[error("serde_v8 error: invalid type, expected: buffer")]
- ExpectedBuffer,
- #[error("serde_v8 error: invalid type, expected: detachable")]
- ExpectedDetachable,
- #[error("serde_v8 error: invalid type, expected: external")]
- ExpectedExternal,
- #[error("serde_v8 error: invalid type, expected: bigint")]
- ExpectedBigInt,
+ #[error("serde_v8 error: invalid type; expected: boolean, got: {0}")]
+ ExpectedBoolean(&'static str),
+
+ #[error("serde_v8 error: invalid type; expected: integer, got: {0}")]
+ ExpectedInteger(&'static str),
+
+ #[error("serde_v8 error: invalid type; expected: number, got: {0}")]
+ ExpectedNumber(&'static str),
+
+ #[error("serde_v8 error: invalid type; expected: string, got: {0}")]
+ ExpectedString(&'static str),
+
+ #[error("serde_v8 error: invalid type; expected: array, got: {0}")]
+ ExpectedArray(&'static str),
+
+ #[error("serde_v8 error: invalid type; expected: map, got: {0}")]
+ ExpectedMap(&'static str),
+
+ #[error("serde_v8 error: invalid type; expected: enum, got: {0}")]
+ ExpectedEnum(&'static str),
+
+ #[error("serde_v8 error: invalid type; expected: object, got: {0}")]
+ ExpectedObject(&'static str),
+
+ #[error("serde_v8 error: invalid type; expected: buffer, got: {0}")]
+ ExpectedBuffer(&'static str),
+
+ #[error("serde_v8 error: invalid type; expected: detachable, got: {0}")]
+ ExpectedDetachable(&'static str),
+
+ #[error("serde_v8 error: invalid type; expected: external, got: {0}")]
+ ExpectedExternal(&'static str),
+
+ #[error("serde_v8 error: invalid type; expected: bigint, got: {0}")]
+ ExpectedBigInt(&'static str),
#[error("serde_v8 error: invalid type, expected: utf8")]
ExpectedUtf8,
@@ -57,3 +68,89 @@ impl serde::de::Error for Error {
Error::Message(msg.to_string())
}
}
+
+pub(crate) fn value_to_type_str(value: v8::Local<v8::Value>) -> &'static str {
+ if value.is_module_namespace_object() {
+ "Module"
+ } else if value.is_wasm_module_object() {
+ "WASM module"
+ } else if value.is_wasm_memory_object() {
+ "WASM memory object"
+ } else if value.is_proxy() {
+ "Proxy"
+ } else if value.is_shared_array_buffer() {
+ "SharedArrayBuffer"
+ } else if value.is_data_view() {
+ "DataView"
+ } else if value.is_big_uint64_array() {
+ "BigUint64Array"
+ } else if value.is_big_int64_array() {
+ "BigInt64Array"
+ } else if value.is_float64_array() {
+ "Float64Array"
+ } else if value.is_float32_array() {
+ "Float32Array"
+ } else if value.is_int32_array() {
+ "Int32Array"
+ } else if value.is_uint32_array() {
+ "Uint32Array"
+ } else if value.is_int16_array() {
+ "Int16Array"
+ } else if value.is_uint16_array() {
+ "Uint16Array"
+ } else if value.is_int8_array() {
+ "Int8Array"
+ } else if value.is_uint8_clamped_array() {
+ "Uint8ClampedArray"
+ } else if value.is_uint8_array() {
+ "Uint8Array"
+ } else if value.is_typed_array() {
+ "TypedArray"
+ } else if value.is_array_buffer_view() {
+ "ArrayBufferView"
+ } else if value.is_array_buffer() {
+ "ArrayBuffer"
+ } else if value.is_weak_set() {
+ "WeakSet"
+ } else if value.is_weak_map() {
+ "WeakMap"
+ } else if value.is_set_iterator() {
+ "Set Iterator"
+ } else if value.is_map_iterator() {
+ "Map Iterator"
+ } else if value.is_set() {
+ "Set"
+ } else if value.is_map() {
+ "Map"
+ } else if value.is_promise() {
+ "Promise"
+ } else if value.is_generator_function() {
+ "Generator function"
+ } else if value.is_async_function() {
+ "Async function"
+ } else if value.is_reg_exp() {
+ "RegExp"
+ } else if value.is_date() {
+ "Date"
+ } else if value.is_number() {
+ "Number"
+ } else if value.is_boolean() {
+ "Boolean"
+ } else if value.is_big_int() {
+ "bigint"
+ } else if value.is_array() {
+ "array"
+ } else if value.is_function() {
+ "function"
+ } else if value.is_symbol() {
+ "symbol"
+ } else if value.is_string() {
+ "string"
+ } else if value.is_null() {
+ "null"
+ } else if value.is_undefined() {
+ "undefined"
+ } else {
+ "unknown"
+ }
+}
diff --git a/serde_v8/magic/bigint.rs b/serde_v8/magic/bigint.rs
index 69828747f..330803daf 100644
--- a/serde_v8/magic/bigint.rs
+++ b/serde_v8/magic/bigint.rs
@@ -5,6 +5,7 @@ use smallvec::SmallVec;
use super::transl8::FromV8;
use super::transl8::ToV8;
+use crate::error::value_to_type_str;
use crate::magic::transl8::impl_magic;
use crate::Error;
@@ -42,7 +43,7 @@ impl FromV8 for BigInt {
value: v8::Local<v8::Value>,
) -> Result<Self, crate::Error> {
let v8bigint = v8::Local::<v8::BigInt>::try_from(value)
- .map_err(|_| Error::ExpectedBigInt)?;
+ .map_err(|_| Error::ExpectedBigInt(value_to_type_str(value)))?;
let word_count = v8bigint.word_count();
let mut words: SmallVec<[u64; 1]> = smallvec![0u64; word_count];
let (sign_bit, _words) = v8bigint.to_words_array(&mut words);
diff --git a/serde_v8/magic/bytestring.rs b/serde_v8/magic/bytestring.rs
index 77771698f..3baa704e5 100644
--- a/serde_v8/magic/bytestring.rs
+++ b/serde_v8/magic/bytestring.rs
@@ -1,6 +1,7 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use super::transl8::FromV8;
use super::transl8::ToV8;
+use crate::error::value_to_type_str;
use crate::magic::transl8::impl_magic;
use crate::Error;
use smallvec::SmallVec;
@@ -49,7 +50,7 @@ impl FromV8 for ByteString {
value: v8::Local<v8::Value>,
) -> Result<Self, crate::Error> {
let v8str = v8::Local::<v8::String>::try_from(value)
- .map_err(|_| Error::ExpectedString)?;
+ .map_err(|_| Error::ExpectedString(value_to_type_str(value)))?;
if !v8str.contains_only_onebyte() {
return Err(Error::ExpectedLatin1);
}
diff --git a/serde_v8/magic/detached_buffer.rs b/serde_v8/magic/detached_buffer.rs
index 7ee4dfb21..bc4b3de67 100644
--- a/serde_v8/magic/detached_buffer.rs
+++ b/serde_v8/magic/detached_buffer.rs
@@ -8,6 +8,7 @@ use super::transl8::FromV8;
use super::transl8::ToV8;
use super::v8slice::to_ranged_buffer;
use super::v8slice::V8Slice;
+use crate::error::value_to_type_str;
use crate::magic::transl8::impl_magic;
// A buffer that detaches when deserialized from JS
@@ -57,10 +58,10 @@ impl FromV8 for DetachedBuffer {
scope: &mut v8::HandleScope,
value: v8::Local<v8::Value>,
) -> Result<Self, crate::Error> {
- let (b, range) =
- to_ranged_buffer(scope, value).or(Err(crate::Error::ExpectedBuffer))?;
+ let (b, range) = to_ranged_buffer(scope, value)
+ .map_err(|_| crate::Error::ExpectedBuffer(value_to_type_str(value)))?;
if !b.is_detachable() {
- return Err(crate::Error::ExpectedDetachable);
+ return Err(crate::Error::ExpectedDetachable(value_to_type_str(value)));
}
let store = b.get_backing_store();
b.detach(None); // Detach
diff --git a/serde_v8/magic/external_pointer.rs b/serde_v8/magic/external_pointer.rs
index fca6028d6..e22e41a01 100644
--- a/serde_v8/magic/external_pointer.rs
+++ b/serde_v8/magic/external_pointer.rs
@@ -2,6 +2,8 @@
use std::ffi::c_void;
+use crate::error::value_to_type_str;
+
use super::transl8::impl_magic;
use super::transl8::FromV8;
use super::transl8::ToV8;
@@ -38,7 +40,7 @@ impl FromV8 for ExternalPointer {
} else if let Ok(external) = v8::Local::<v8::External>::try_from(value) {
Ok(ExternalPointer(external.value()))
} else {
- Err(crate::Error::ExpectedExternal)
+ Err(crate::Error::ExpectedExternal(value_to_type_str(value)))
}
}
}
diff --git a/serde_v8/magic/string_or_buffer.rs b/serde_v8/magic/string_or_buffer.rs
index 04ce08be2..8b1a06dbc 100644
--- a/serde_v8/magic/string_or_buffer.rs
+++ b/serde_v8/magic/string_or_buffer.rs
@@ -2,6 +2,7 @@
use super::buffer::ZeroCopyBuf;
use super::transl8::FromV8;
use super::transl8::ToV8;
+use crate::error::value_to_type_str;
use crate::magic::transl8::impl_magic;
use crate::Error;
use std::ops::Deref;
@@ -73,7 +74,7 @@ impl FromV8 for StringOrBuffer {
} else if let Ok(s) = crate::from_v8(scope, value) {
return Ok(Self::String(s));
}
- Err(Error::ExpectedBuffer)
+ Err(Error::ExpectedBuffer(value_to_type_str(value)))
}
}
diff --git a/serde_v8/magic/u16string.rs b/serde_v8/magic/u16string.rs
index 57e3fd0f6..04d742da9 100644
--- a/serde_v8/magic/u16string.rs
+++ b/serde_v8/magic/u16string.rs
@@ -1,5 +1,6 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
+use crate::error::value_to_type_str;
use crate::Error;
use super::transl8::impl_magic;
@@ -37,7 +38,7 @@ impl FromV8 for U16String {
value: v8::Local<v8::Value>,
) -> Result<Self, crate::Error> {
let v8str = v8::Local::<v8::String>::try_from(value)
- .map_err(|_| Error::ExpectedString)?;
+ .map_err(|_| Error::ExpectedString(value_to_type_str(value)))?;
let len = v8str.length();
let mut buffer = Vec::with_capacity(len);
#[allow(clippy::uninit_vec)]
diff --git a/serde_v8/magic/v8slice.rs b/serde_v8/magic/v8slice.rs
index 384ccf5c5..073e75235 100644
--- a/serde_v8/magic/v8slice.rs
+++ b/serde_v8/magic/v8slice.rs
@@ -5,6 +5,8 @@ use std::ops::DerefMut;
use std::ops::Range;
use std::rc::Rc;
+use crate::error::value_to_type_str;
+
use super::rawbytes;
use super::transl8::FromV8;
@@ -91,7 +93,7 @@ impl FromV8 for V8Slice {
) -> Result<Self, crate::Error> {
to_ranged_buffer(scope, value)
.and_then(|(b, r)| Self::from_buffer(b, r))
- .map_err(|_| crate::Error::ExpectedBuffer)
+ .map_err(|_| crate::Error::ExpectedBuffer(value_to_type_str(value)))
}
}
diff --git a/serde_v8/tests/de.rs b/serde_v8/tests/de.rs
index eae30f540..4e5e1e4b9 100644
--- a/serde_v8/tests/de.rs
+++ b/serde_v8/tests/de.rs
@@ -408,7 +408,7 @@ detest!(
);
defail!(defail_struct, MathOp, "123", |e| e
- == Err(Error::ExpectedObject));
+ == Err(Error::ExpectedObject("Number")));
#[derive(Eq, PartialEq, Debug, Deserialize)]
pub struct SomeThing {