Repository: denoland/deno_core
Pull request #1033 (2025-01-06 21:04:39)

perf: reduce generated error handling code in ops
deno release build is about 700kb smaller with this patch
```
110239496 this patch
110942920 main
```


Patch:
diff --git a/core/error.rs b/core/error.rs
index 8974fff..1e22e65 100644
--- a/core/error.rs
+++ b/core/error.rs
@@ -1723,6 +1723,36 @@ pub fn format_frame<F: ErrorFormat>(frame: &JsStackFrame) -> String {
   result
 }
 
+pub fn throw_error_one_byte_info(
+  info: &v8::FunctionCallbackInfo,
+  message: &str,
+) {
+  let mut scope = unsafe { v8::CallbackScope::new(info) };
+  throw_error_one_byte(&mut scope, message);
+}
+
+pub fn throw_error_anyhow<S>(scope: &mut v8::CallbackScope<'_>, message: S)
+where
+  S: Into<deno_core::anyhow::Error>,
+{
+  // TODO(mmastrac): This might be allocating too much, even if it's on the error path
+  let e: deno_core::anyhow::Error = message.into();
+  let msg = deno_core::v8::String::new(scope, &format!("{}", e)).unwrap();
+  let exc = deno_core::v8::Exception::type_error(scope, msg);
+  scope.throw_exception(exc);
+}
+
+pub fn throw_error_one_byte(scope: &mut v8::CallbackScope, message: &str) {
+  let msg = deno_core::v8::String::new_from_one_byte(
+    scope,
+    message.as_bytes(),
+    deno_core::v8::NewStringType::Normal,
+  )
+  .unwrap();
+  let exc = deno_core::v8::Exception::type_error(scope, msg);
+  scope.throw_exception(exc);
+}
+
 #[cfg(test)]
 mod tests {
   use super::*;
diff --git a/core/lib.rs b/core/lib.rs
index 82821fd..5f92ffd 100644
--- a/core/lib.rs
+++ b/core/lib.rs
@@ -177,6 +177,9 @@ extern crate self as deno_core;
 pub mod _ops {
   pub use super::cppgc::make_cppgc_object;
   pub use super::cppgc::try_unwrap_cppgc_object;
+  pub use super::error::throw_error_anyhow;
+  pub use super::error::throw_error_one_byte;
+  pub use super::error::throw_error_one_byte_info;
   pub use super::error::throw_type_error;
   pub use super::error_codes::get_error_code;
   pub use super::extensions::Op;
diff --git a/ops/op2/dispatch_fast.rs b/ops/op2/dispatch_fast.rs
index d13b50d..06582b0 100644
--- a/ops/op2/dispatch_fast.rs
+++ b/ops/op2/dispatch_fast.rs
@@ -332,9 +332,7 @@ fn throw_type_error(
   let message = format!("{message}");
   quote!({
     let mut scope = #create_scope;
-    let msg = deno_core::v8::String::new_from_one_byte(&mut scope, #message.as_bytes(), deno_core::v8::NewStringType::Normal).unwrap();
-    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-    scope.throw_exception(exc);
+    deno_core::_ops::throw_error_one_byte(&mut scope, #message);
     // SAFETY: All fast return types have zero as a valid value
     return unsafe { std::mem::zeroed() };
   })
diff --git a/ops/op2/dispatch_slow.rs b/ops/op2/dispatch_slow.rs
index 78dfe1e..7aa86d7 100644
--- a/ops/op2/dispatch_slow.rs
+++ b/ops/op2/dispatch_slow.rs
@@ -1190,17 +1190,8 @@ fn throw_type_error(
   // Sanity check ASCII and a valid/reasonable message size
   debug_assert!(message.is_ascii() && message.len() < 1024);
 
-  let maybe_scope = if generator_state.needs_scope {
-    quote!()
-  } else {
-    with_scope(generator_state)
-  };
-
-  Ok(gs_quote!(generator_state(scope) => {
-    #maybe_scope
-    let msg = deno_core::v8::String::new_from_one_byte(&mut #scope, #message.as_bytes(), deno_core::v8::NewStringType::Normal).unwrap();
-    let exc = deno_core::v8::Exception::type_error(&mut #scope, msg);
-    #scope.throw_exception(exc);
+  Ok(gs_quote!(generator_state(info) => {
+    deno_core::_ops::throw_error_one_byte_info(&#info, #message);
     return 1;
   }))
 }
@@ -1218,10 +1209,7 @@ fn throw_type_error_string(
 
   Ok(gs_quote!(generator_state(scope) => {
     #maybe_scope
-    // TODO(mmastrac): This might be allocating too much, even if it's on the error path
-    let msg = deno_core::v8::String::new(&mut #scope, &format!("{}", deno_core::anyhow::Error::from(#message))).unwrap();
-    let exc = deno_core::v8::Exception::type_error(&mut #scope, msg);
-    #scope.throw_exception(exc);
+    deno_core::_ops::throw_error_anyhow(&mut #scope, #message);
     return 1;
   }))
 }
@@ -1231,17 +1219,8 @@ fn throw_type_error_static_string(
   generator_state: &mut GeneratorState,
   message: &Ident,
 ) -> Result<TokenStream, V8MappingError> {
-  let maybe_scope = if generator_state.needs_scope {
-    quote!()
-  } else {
-    with_scope(generator_state)
-  };
-
-  Ok(gs_quote!(generator_state(scope) => {
-    #maybe_scope
-    let msg = deno_core::v8::String::new_from_one_byte(&mut #scope, #message.as_bytes(), deno_core::v8::NewStringType::Normal).unwrap();
-    let exc = deno_core::v8::Exception::type_error(&mut #scope, msg);
-    #scope.throw_exception(exc);
+  Ok(gs_quote!(generator_state(info) => {
+    deno_core::_ops::throw_error_one_byte_info(&#info, #message);
     return 1;
   }))
 }


Test patch:
diff --git a/ops/op2/test_cases/async/async_arg_return.out b/ops/op2/test_cases/async/async_arg_return.out
index 9a7610f..acf77d7 100644
--- a/ops/op2/test_cases/async/async_arg_return.out
+++ b/ops/op2/test_cases/async/async_arg_return.out
@@ -47,15 +47,7 @@ pub const fn op_async() -> ::deno_core::_ops::OpDecl {
             let result = {
                 let arg0 = args.get(1usize as i32);
                 let Some(arg0) = deno_core::_ops::to_i32_option(&arg0) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected i32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected i32");
                     return 1;
                 };
                 let arg0 = arg0 as _;
diff --git a/ops/op2/test_cases/async/async_arg_return_result.out b/ops/op2/test_cases/async/async_arg_return_result.out
index 12ad8fb..a9b006e 100644
--- a/ops/op2/test_cases/async/async_arg_return_result.out
+++ b/ops/op2/test_cases/async/async_arg_return_result.out
@@ -47,15 +47,7 @@ pub const fn op_async() -> ::deno_core::_ops::OpDecl {
             let result = {
                 let arg0 = args.get(1usize as i32);
                 let Some(arg0) = deno_core::_ops::to_i32_option(&arg0) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected i32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected i32");
                     return 1;
                 };
                 let arg0 = arg0 as _;
diff --git a/ops/op2/test_cases/async/async_cppgc.out b/ops/op2/test_cases/async/async_cppgc.out
index 69cdd08..782a8b9 100644
--- a/ops/op2/test_cases/async/async_cppgc.out
+++ b/ops/op2/test_cases/async/async_cppgc.out
@@ -175,14 +175,7 @@ const fn op_use_cppgc_object() -> ::deno_core::_ops::OpDecl {
                 let Some(mut arg0) = deno_core::_ops::try_unwrap_cppgc_object::<
                     Wrap,
                 >(&mut scope, arg0) else {
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected Wrap".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected Wrap");
                     return 1;
                 };
                 arg0.root();
@@ -305,14 +298,7 @@ const fn op_use_optional_cppgc_object() -> ::deno_core::_ops::OpDecl {
                     arg0.root();
                     Some(arg0)
                 } else {
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected Wrap".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected Wrap");
                     return 1;
                 };
                 async move {
diff --git a/ops/op2/test_cases/async/async_jsbuffer.out b/ops/op2/test_cases/async/async_jsbuffer.out
index 4a2c728..fc452bf 100644
--- a/ops/op2/test_cases/async/async_jsbuffer.out
+++ b/ops/op2/test_cases/async/async_jsbuffer.out
@@ -51,17 +51,7 @@ pub const fn op_async_v8_buffer() -> ::deno_core::_ops::OpDecl {
                 arg0_temp = match unsafe { deno_core::_ops::to_v8_slice::<u8>(arg0) } {
                     Ok(arg0) => arg0,
                     Err(arg0_err) => {
-                        let mut scope = unsafe {
-                            deno_core::v8::CallbackScope::new(info)
-                        };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                arg0_err.as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte_info(&info, arg0_err);
                         return 1;
                     }
                 };
@@ -86,13 +76,7 @@ pub const fn op_async_v8_buffer() -> ::deno_core::_ops::OpDecl {
                 ) {
                     Ok(v) => rv.set(v),
                     Err(rv_err) => {
-                        let msg = deno_core::v8::String::new(
-                                &mut scope,
-                                &format!("{}", deno_core::anyhow::Error::from(rv_err)),
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_anyhow(&mut scope, rv_err);
                         return 1;
                     }
                 };
diff --git a/ops/op2/test_cases/async/async_result_impl.out b/ops/op2/test_cases/async/async_result_impl.out
index 59d459b..bae8ff1 100644
--- a/ops/op2/test_cases/async/async_result_impl.out
+++ b/ops/op2/test_cases/async/async_result_impl.out
@@ -47,15 +47,7 @@ pub const fn op_async_result_impl() -> ::deno_core::_ops::OpDecl {
             let result = {
                 let arg0 = args.get(1usize as i32);
                 let Some(arg0) = deno_core::_ops::to_i32_option(&arg0) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected i32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected i32");
                     return 1;
                 };
                 let arg0 = arg0 as _;
diff --git a/ops/op2/test_cases/async/async_result_smi.out b/ops/op2/test_cases/async/async_result_smi.out
index a7c0720..b67fc8d 100644
--- a/ops/op2/test_cases/async/async_result_smi.out
+++ b/ops/op2/test_cases/async/async_result_smi.out
@@ -47,15 +47,7 @@ pub const fn op_async() -> ::deno_core::_ops::OpDecl {
             let result = {
                 let arg0 = args.get(1usize as i32);
                 let Some(arg0) = deno_core::_ops::to_i32_option(&arg0) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected i32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected i32");
                     return 1;
                 };
                 let arg0 = arg0 as _;
diff --git a/ops/op2/test_cases/async/async_v8_global.out b/ops/op2/test_cases/async/async_v8_global.out
index d8f6957..04f267f 100644
--- a/ops/op2/test_cases/async/async_v8_global.out
+++ b/ops/op2/test_cases/async/async_v8_global.out
@@ -50,15 +50,7 @@ pub const fn op_async_v8_global() -> ::deno_core::_ops::OpDecl {
                 let Ok(mut arg0) = deno_core::_ops::v8_try_convert::<
                     deno_core::v8::String,
                 >(arg0) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected String".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected String");
                     return 1;
                 };
                 let arg0 = deno_core::v8::Global::new(&mut scope, arg0);
diff --git a/ops/op2/test_cases/sync/add.out b/ops/op2/test_cases/sync/add.out
index 82a2d30..9cdad80 100644
--- a/ops/op2/test_cases/sync/add.out
+++ b/ops/op2/test_cases/sync/add.out
@@ -142,29 +142,13 @@ const fn op_add() -> ::deno_core::_ops::OpDecl {
             let result = {
                 let arg0 = args.get(0usize as i32);
                 let Some(arg0) = deno_core::_ops::to_u32_option(&arg0) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected u32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected u32");
                     return 1;
                 };
                 let arg0 = arg0 as _;
                 let arg1 = args.get(1usize as i32);
                 let Some(arg1) = deno_core::_ops::to_u32_option(&arg1) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected u32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected u32");
                     return 1;
                 };
                 let arg1 = arg1 as _;
diff --git a/ops/op2/test_cases/sync/add_options.out b/ops/op2/test_cases/sync/add_options.out
index 908e3f9..712938f 100644
--- a/ops/op2/test_cases/sync/add_options.out
+++ b/ops/op2/test_cases/sync/add_options.out
@@ -41,15 +41,7 @@ pub const fn op_test_add_option() -> ::deno_core::_ops::OpDecl {
             let result = {
                 let arg0 = args.get(0usize as i32);
                 let Some(arg0) = deno_core::_ops::to_u32_option(&arg0) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected u32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected u32");
                     return 1;
                 };
                 let arg0 = arg0 as _;
@@ -58,17 +50,10 @@ pub const fn op_test_add_option() -> ::deno_core::_ops::OpDecl {
                     None
                 } else {
                     let Some(arg1) = deno_core::_ops::to_u32_option(&arg1) else {
-                        let mut scope = unsafe {
-                            deno_core::v8::CallbackScope::new(info)
-                        };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                "expected u32".as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte_info(
+                            &info,
+                            "expected u32",
+                        );
                         return 1;
                     };
                     let arg1 = arg1 as _;
diff --git a/ops/op2/test_cases/sync/buffers.out b/ops/op2/test_cases/sync/buffers.out
index 74079d4..f4096b4 100644
--- a/ops/op2/test_cases/sync/buffers.out
+++ b/ops/op2/test_cases/sync/buffers.out
@@ -151,17 +151,7 @@ const fn op_buffers() -> ::deno_core::_ops::OpDecl {
                 arg0_temp = match unsafe { deno_core::_ops::to_v8_slice::<u8>(arg0) } {
                     Ok(arg0) => arg0,
                     Err(arg0_err) => {
-                        let mut scope = unsafe {
-                            deno_core::v8::CallbackScope::new(info)
-                        };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                arg0_err.as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte_info(&info, arg0_err);
                         return 1;
                     }
                 };
@@ -171,17 +161,7 @@ const fn op_buffers() -> ::deno_core::_ops::OpDecl {
                 arg1_temp = match unsafe { deno_core::_ops::to_v8_slice::<u8>(arg1) } {
                     Ok(arg1) => arg1,
                     Err(arg1_err) => {
-                        let mut scope = unsafe {
-                            deno_core::v8::CallbackScope::new(info)
-                        };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                arg1_err.as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte_info(&info, arg1_err);
                         return 1;
                     }
                 };
@@ -191,17 +171,7 @@ const fn op_buffers() -> ::deno_core::_ops::OpDecl {
                 arg2_temp = match unsafe { deno_core::_ops::to_v8_slice::<u8>(arg2) } {
                     Ok(arg2) => arg2,
                     Err(arg2_err) => {
-                        let mut scope = unsafe {
-                            deno_core::v8::CallbackScope::new(info)
-                        };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                arg2_err.as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte_info(&info, arg2_err);
                         return 1;
                     }
                 };
@@ -215,17 +185,7 @@ const fn op_buffers() -> ::deno_core::_ops::OpDecl {
                 arg3_temp = match unsafe { deno_core::_ops::to_v8_slice::<u8>(arg3) } {
                     Ok(arg3) => arg3,
                     Err(arg3_err) => {
-                        let mut scope = unsafe {
-                            deno_core::v8::CallbackScope::new(info)
-                        };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                arg3_err.as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte_info(&info, arg3_err);
                         return 1;
                     }
                 };
@@ -434,17 +394,7 @@ const fn op_buffers_32() -> ::deno_core::_ops::OpDecl {
                 arg0_temp = match unsafe { deno_core::_ops::to_v8_slice::<u32>(arg0) } {
                     Ok(arg0) => arg0,
                     Err(arg0_err) => {
-                        let mut scope = unsafe {
-                            deno_core::v8::CallbackScope::new(info)
-                        };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                arg0_err.as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte_info(&info, arg0_err);
                         return 1;
                     }
                 };
@@ -454,17 +404,7 @@ const fn op_buffers_32() -> ::deno_core::_ops::OpDecl {
                 arg1_temp = match unsafe { deno_core::_ops::to_v8_slice::<u32>(arg1) } {
                     Ok(arg1) => arg1,
                     Err(arg1_err) => {
-                        let mut scope = unsafe {
-                            deno_core::v8::CallbackScope::new(info)
-                        };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                arg1_err.as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte_info(&info, arg1_err);
                         return 1;
                     }
                 };
@@ -474,17 +414,7 @@ const fn op_buffers_32() -> ::deno_core::_ops::OpDecl {
                 arg2_temp = match unsafe { deno_core::_ops::to_v8_slice::<u32>(arg2) } {
                     Ok(arg2) => arg2,
                     Err(arg2_err) => {
-                        let mut scope = unsafe {
-                            deno_core::v8::CallbackScope::new(info)
-                        };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                arg2_err.as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte_info(&info, arg2_err);
                         return 1;
                     }
                 };
@@ -498,17 +428,7 @@ const fn op_buffers_32() -> ::deno_core::_ops::OpDecl {
                 arg3_temp = match unsafe { deno_core::_ops::to_v8_slice::<u32>(arg3) } {
                     Ok(arg3) => arg3,
                     Err(arg3_err) => {
-                        let mut scope = unsafe {
-                            deno_core::v8::CallbackScope::new(info)
-                        };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                arg3_err.as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte_info(&info, arg3_err);
                         return 1;
                     }
                 };
@@ -615,20 +535,7 @@ const fn op_buffers_option() -> ::deno_core::_ops::OpDecl {
                     } {
                         Ok(arg0) => arg0,
                         Err(arg0_err) => {
-                            let mut scope = unsafe {
-                                deno_core::v8::CallbackScope::new(info)
-                            };
-                            let msg = deno_core::v8::String::new_from_one_byte(
-                                    &mut scope,
-                                    arg0_err.as_bytes(),
-                                    deno_core::v8::NewStringType::Normal,
-                                )
-                                .unwrap();
-                            let exc = deno_core::v8::Exception::type_error(
-                                &mut scope,
-                                msg,
-                            );
-                            scope.throw_exception(exc);
+                            deno_core::_ops::throw_error_one_byte_info(&info, arg0_err);
                             return 1;
                         }
                     };
@@ -645,20 +552,7 @@ const fn op_buffers_option() -> ::deno_core::_ops::OpDecl {
                     } {
                         Ok(arg1) => arg1,
                         Err(arg1_err) => {
-                            let mut scope = unsafe {
-                                deno_core::v8::CallbackScope::new(info)
-                            };
-                            let msg = deno_core::v8::String::new_from_one_byte(
-                                    &mut scope,
-                                    arg1_err.as_bytes(),
-                                    deno_core::v8::NewStringType::Normal,
-                                )
-                                .unwrap();
-                            let exc = deno_core::v8::Exception::type_error(
-                                &mut scope,
-                                msg,
-                            );
-                            scope.throw_exception(exc);
+                            deno_core::_ops::throw_error_one_byte_info(&info, arg1_err);
                             return 1;
                         }
                     };
diff --git a/ops/op2/test_cases/sync/buffers_copy.out b/ops/op2/test_cases/sync/buffers_copy.out
index e4e8e94..68e01f3 100644
--- a/ops/op2/test_cases/sync/buffers_copy.out
+++ b/ops/op2/test_cases/sync/buffers_copy.out
@@ -135,17 +135,7 @@ const fn op_buffers() -> ::deno_core::_ops::OpDecl {
                 arg0_temp = match unsafe { deno_core::_ops::to_v8_slice::<u8>(arg0) } {
                     Ok(arg0) => arg0,
                     Err(arg0_err) => {
-                        let mut scope = unsafe {
-                            deno_core::v8::CallbackScope::new(info)
-                        };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                arg0_err.as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte_info(&info, arg0_err);
                         return 1;
                     }
                 };
@@ -155,17 +145,7 @@ const fn op_buffers() -> ::deno_core::_ops::OpDecl {
                 arg1_temp = match unsafe { deno_core::_ops::to_v8_slice::<u8>(arg1) } {
                     Ok(arg1) => arg1,
                     Err(arg1_err) => {
-                        let mut scope = unsafe {
-                            deno_core::v8::CallbackScope::new(info)
-                        };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                arg1_err.as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte_info(&info, arg1_err);
                         return 1;
                     }
                 };
@@ -175,17 +155,7 @@ const fn op_buffers() -> ::deno_core::_ops::OpDecl {
                 arg2_temp = match unsafe { deno_core::_ops::to_v8_slice::<u8>(arg2) } {
                     Ok(arg2) => arg2,
                     Err(arg2_err) => {
-                        let mut scope = unsafe {
-                            deno_core::v8::CallbackScope::new(info)
-                        };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                arg2_err.as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte_info(&info, arg2_err);
                         return 1;
                     }
                 };
@@ -366,17 +336,7 @@ const fn op_buffers_32() -> ::deno_core::_ops::OpDecl {
                 arg0_temp = match unsafe { deno_core::_ops::to_v8_slice::<u32>(arg0) } {
                     Ok(arg0) => arg0,
                     Err(arg0_err) => {
-                        let mut scope = unsafe {
-                            deno_core::v8::CallbackScope::new(info)
-                        };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                arg0_err.as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte_info(&info, arg0_err);
                         return 1;
                     }
                 };
@@ -386,17 +346,7 @@ const fn op_buffers_32() -> ::deno_core::_ops::OpDecl {
                 arg1_temp = match unsafe { deno_core::_ops::to_v8_slice::<u32>(arg1) } {
                     Ok(arg1) => arg1,
                     Err(arg1_err) => {
-                        let mut scope = unsafe {
-                            deno_core::v8::CallbackScope::new(info)
-                        };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                arg1_err.as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte_info(&info, arg1_err);
                         return 1;
                     }
                 };
diff --git a/ops/op2/test_cases/sync/buffers_out.out b/ops/op2/test_cases/sync/buffers_out.out
index bbb593b..0463200 100644
--- a/ops/op2/test_cases/sync/buffers_out.out
+++ b/ops/op2/test_cases/sync/buffers_out.out
@@ -45,17 +45,7 @@ const fn op_buffers() -> ::deno_core::_ops::OpDecl {
                 arg0_temp = match unsafe { deno_core::_ops::to_v8_slice::<u8>(arg0) } {
                     Ok(arg0) => arg0,
                     Err(arg0_err) => {
-                        let mut scope = unsafe {
-                            deno_core::v8::CallbackScope::new(info)
-                        };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                arg0_err.as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte_info(&info, arg0_err);
                         return 1;
                     }
                 };
@@ -65,13 +55,7 @@ const fn op_buffers() -> ::deno_core::_ops::OpDecl {
             match deno_core::_ops::RustToV8Fallible::to_v8_fallible(result, &mut scope) {
                 Ok(v) => rv.set(v),
                 Err(rv_err) => {
-                    let msg = deno_core::v8::String::new(
-                            &mut scope,
-                            &format!("{}", deno_core::anyhow::Error::from(rv_err)),
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_anyhow(&mut scope, rv_err);
                     return 1;
                 }
             };
@@ -173,20 +157,7 @@ const fn op_buffers_option() -> ::deno_core::_ops::OpDecl {
                     } {
                         Ok(arg0) => arg0,
                         Err(arg0_err) => {
-                            let mut scope = unsafe {
-                                deno_core::v8::CallbackScope::new(info)
-                            };
-                            let msg = deno_core::v8::String::new_from_one_byte(
-                                    &mut scope,
-                                    arg0_err.as_bytes(),
-                                    deno_core::v8::NewStringType::Normal,
-                                )
-                                .unwrap();
-                            let exc = deno_core::v8::Exception::type_error(
-                                &mut scope,
-                                msg,
-                            );
-                            scope.throw_exception(exc);
+                            deno_core::_ops::throw_error_one_byte_info(&info, arg0_err);
                             return 1;
                         }
                     };
@@ -198,13 +169,7 @@ const fn op_buffers_option() -> ::deno_core::_ops::OpDecl {
             match deno_core::_ops::RustToV8Fallible::to_v8_fallible(result, &mut scope) {
                 Ok(v) => rv.set(v),
                 Err(rv_err) => {
-                    let msg = deno_core::v8::String::new(
-                            &mut scope,
-                            &format!("{}", deno_core::anyhow::Error::from(rv_err)),
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_anyhow(&mut scope, rv_err);
                     return 1;
                 }
             };
@@ -301,17 +266,7 @@ const fn op_arraybuffers() -> ::deno_core::_ops::OpDecl {
                 arg0_temp = match unsafe { deno_core::_ops::to_v8_slice_buffer(arg0) } {
                     Ok(arg0) => arg0,
                     Err(arg0_err) => {
-                        let mut scope = unsafe {
-                            deno_core::v8::CallbackScope::new(info)
-                        };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                arg0_err.as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte_info(&info, arg0_err);
                         return 1;
                     }
                 };
diff --git a/ops/op2/test_cases/sync/cppgc_resource.out b/ops/op2/test_cases/sync/cppgc_resource.out
index b1d2408..ac8eeaa 100644
--- a/ops/op2/test_cases/sync/cppgc_resource.out
+++ b/ops/op2/test_cases/sync/cppgc_resource.out
@@ -111,15 +111,10 @@ const fn op_cppgc_object() -> ::deno_core::_ops::OpDecl {
                                 &*fast_api_callback_options,
                             )
                         };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                "expected Path { leading_colon: None, segments: [PathSegment { ident: Ident(Wrap), arguments: PathArguments::None }] }"
-                                    .as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte(
+                            &mut scope,
+                            "expected Path { leading_colon: None, segments: [PathSegment { ident: Ident(Wrap), arguments: PathArguments::None }] }",
+                        );
                         return unsafe { std::mem::zeroed() };
                     }
                 };
@@ -145,14 +140,7 @@ const fn op_cppgc_object() -> ::deno_core::_ops::OpDecl {
                 let Some(arg0) = deno_core::_ops::try_unwrap_cppgc_object::<
                     Wrap,
                 >(&mut scope, arg0) else {
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected Wrap".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected Wrap");
                     return 1;
                 };
                 let arg0 = &*arg0;
@@ -320,15 +308,10 @@ const fn op_option_cppgc_object() -> ::deno_core::_ops::OpDecl {
                                 &*fast_api_callback_options,
                             )
                         };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                "expected Path { leading_colon: None, segments: [PathSegment { ident: Ident(Wrap), arguments: PathArguments::None }] }"
-                                    .as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte(
+                            &mut scope,
+                            "expected Path { leading_colon: None, segments: [PathSegment { ident: Ident(Wrap), arguments: PathArguments::None }] }",
+                        );
                         return unsafe { std::mem::zeroed() };
                     }
                 };
@@ -358,14 +341,7 @@ const fn op_option_cppgc_object() -> ::deno_core::_ops::OpDecl {
                 >(&mut scope, arg0) {
                     Some(arg0)
                 } else {
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected Wrap".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected Wrap");
                     return 1;
                 };
                 let arg0 = arg0.as_deref();
@@ -623,15 +599,10 @@ const fn op_use_cppgc_object() -> ::deno_core::_ops::OpDecl {
                                 &*fast_api_callback_options,
                             )
                         };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                "expected Path { leading_colon: None, segments: [PathSegment { ident: Ident(Wrap), arguments: PathArguments::None }] }"
-                                    .as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte(
+                            &mut scope,
+                            "expected Path { leading_colon: None, segments: [PathSegment { ident: Ident(Wrap), arguments: PathArguments::None }] }",
+                        );
                         return unsafe { std::mem::zeroed() };
                     }
                 };
@@ -657,14 +628,7 @@ const fn op_use_cppgc_object() -> ::deno_core::_ops::OpDecl {
                 let Some(arg0) = deno_core::_ops::try_unwrap_cppgc_object::<
                     Wrap,
                 >(&mut scope, arg0) else {
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected Wrap".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected Wrap");
                     return 1;
                 };
                 let arg0 = &*arg0;
@@ -925,15 +889,10 @@ const fn op_use_cppgc_object_option() -> ::deno_core::_ops::OpDecl {
                                 &*fast_api_callback_options,
                             )
                         };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                "expected Path { leading_colon: None, segments: [PathSegment { ident: Ident(Wrap), arguments: PathArguments::None }] }"
-                                    .as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte(
+                            &mut scope,
+                            "expected Path { leading_colon: None, segments: [PathSegment { ident: Ident(Wrap), arguments: PathArguments::None }] }",
+                        );
                         return unsafe { std::mem::zeroed() };
                     }
                 };
@@ -959,14 +918,7 @@ const fn op_use_cppgc_object_option() -> ::deno_core::_ops::OpDecl {
                 let Some(arg0) = deno_core::_ops::try_unwrap_cppgc_object::<
                     Wrap,
                 >(&mut scope, arg0) else {
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected Wrap".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected Wrap");
                     return 1;
                 };
                 let arg0 = &*arg0;
diff --git a/ops/op2/test_cases/sync/fast_alternative.out b/ops/op2/test_cases/sync/fast_alternative.out
index 6390413..af9fc14 100644
--- a/ops/op2/test_cases/sync/fast_alternative.out
+++ b/ops/op2/test_cases/sync/fast_alternative.out
@@ -42,27 +42,13 @@ const fn op_slow() -> ::deno_core::_ops::OpDecl {
             let result = {
                 let arg1 = args.get(0usize as i32);
                 let Some(arg1) = deno_core::_ops::to_u32_option(&arg1) else {
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected u32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected u32");
                     return 1;
                 };
                 let arg1 = arg1 as _;
                 let arg2 = args.get(1usize as i32);
                 let Some(arg2) = deno_core::_ops::to_u32_option(&arg2) else {
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected u32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected u32");
                     return 1;
                 };
                 let arg2 = arg2 as _;
@@ -260,29 +246,13 @@ const fn op_fast() -> ::deno_core::_ops::OpDecl {
             let result = {
                 let arg0 = args.get(0usize as i32);
                 let Some(arg0) = deno_core::_ops::to_u32_option(&arg0) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected u32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected u32");
                     return 1;
                 };
                 let arg0 = arg0 as _;
                 let arg1 = args.get(1usize as i32);
                 let Some(arg1) = deno_core::_ops::to_u32_option(&arg1) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected u32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected u32");
                     return 1;
                 };
                 let arg1 = arg1 as _;
@@ -379,27 +349,13 @@ const fn op_slow_generic<T: Trait>() -> ::deno_core::_ops::OpDecl {
             let result = {
                 let arg1 = args.get(0usize as i32);
                 let Some(arg1) = deno_core::_ops::to_u32_option(&arg1) else {
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected u32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected u32");
                     return 1;
                 };
                 let arg1 = arg1 as _;
                 let arg2 = args.get(1usize as i32);
                 let Some(arg2) = deno_core::_ops::to_u32_option(&arg2) else {
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected u32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected u32");
                     return 1;
                 };
                 let arg2 = arg2 as _;
@@ -597,29 +553,13 @@ const fn op_fast_generic<T: Trait>() -> ::deno_core::_ops::OpDecl {
             let result = {
                 let arg0 = args.get(0usize as i32);
                 let Some(arg0) = deno_core::_ops::to_u32_option(&arg0) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected u32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected u32");
                     return 1;
                 };
                 let arg0 = arg0 as _;
                 let arg1 = args.get(1usize as i32);
                 let Some(arg1) = deno_core::_ops::to_u32_option(&arg1) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected u32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected u32");
                     return 1;
                 };
                 let arg1 = arg1 as _;
diff --git a/ops/op2/test_cases/sync/from_v8.out b/ops/op2/test_cases/sync/from_v8.out
index c036f41..9b6e35e 100644
--- a/ops/op2/test_cases/sync/from_v8.out
+++ b/ops/op2/test_cases/sync/from_v8.out
@@ -44,13 +44,7 @@ pub const fn op_from_v8_arg() -> ::deno_core::_ops::OpDecl {
                 let arg0 = match <Foo as deno_core::FromV8>::from_v8(&mut scope, arg0) {
                     Ok(t) => t,
                     Err(arg0_err) => {
-                        let msg = deno_core::v8::String::new(
-                                &mut scope,
-                                &format!("{}", deno_core::anyhow::Error::from(arg0_err)),
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_anyhow(&mut scope, arg0_err);
                         return 1;
                     }
                 };
diff --git a/ops/op2/test_cases/sync/nofast.out b/ops/op2/test_cases/sync/nofast.out
index 592ac5c..aac70df 100644
--- a/ops/op2/test_cases/sync/nofast.out
+++ b/ops/op2/test_cases/sync/nofast.out
@@ -41,29 +41,13 @@ const fn op_nofast() -> ::deno_core::_ops::OpDecl {
             let result = {
                 let arg0 = args.get(0usize as i32);
                 let Some(arg0) = deno_core::_ops::to_u32_option(&arg0) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected u32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected u32");
                     return 1;
                 };
                 let arg0 = arg0 as _;
                 let arg1 = args.get(1usize as i32);
                 let Some(arg1) = deno_core::_ops::to_u32_option(&arg1) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected u32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected u32");
                     return 1;
                 };
                 let arg1 = arg1 as _;
diff --git a/ops/op2/test_cases/sync/object_wrap.out b/ops/op2/test_cases/sync/object_wrap.out
index 77c2e28..a57f02e 100644
--- a/ops/op2/test_cases/sync/object_wrap.out
+++ b/ops/op2/test_cases/sync/object_wrap.out
@@ -63,20 +63,10 @@ impl Foo {
                         None
                     } else {
                         let Some(arg0) = deno_core::_ops::to_u32_option(&arg0) else {
-                            let mut scope = unsafe {
-                                deno_core::v8::CallbackScope::new(info)
-                            };
-                            let msg = deno_core::v8::String::new_from_one_byte(
-                                    &mut scope,
-                                    "expected u32".as_bytes(),
-                                    deno_core::v8::NewStringType::Normal,
-                                )
-                                .unwrap();
-                            let exc = deno_core::v8::Exception::type_error(
-                                &mut scope,
-                                msg,
+                            deno_core::_ops::throw_error_one_byte_info(
+                                &info,
+                                "expected u32",
                             );
-                            scope.throw_exception(exc);
                             return 1;
                         };
                         let arg0 = arg0 as _;
@@ -191,14 +181,7 @@ impl Foo {
                 let Some(self_) = deno_core::_ops::try_unwrap_cppgc_object::<
                     Foo,
                 >(&mut scope, args.this().into()) else {
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected Foo".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected Foo");
                     return 1;
                 };
                 let self_ = &*self_;
@@ -297,31 +280,17 @@ impl Foo {
                 let Some(self_) = deno_core::_ops::try_unwrap_cppgc_object::<
                     Foo,
                 >(&mut scope, args.this().into()) else {
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected Foo".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected Foo");
                     return 1;
                 };
                 let self_ = &*self_;
                 let result = {
                     let arg0 = args.get(0usize as i32);
                     let Some(arg0) = deno_core::_ops::to_u32_option(&arg0) else {
-                        let mut scope = unsafe {
-                            deno_core::v8::CallbackScope::new(info)
-                        };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                "expected u32".as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte_info(
+                            &info,
+                            "expected u32",
+                        );
                         return 1;
                     };
                     let arg0 = arg0 as _;
@@ -439,31 +408,17 @@ impl Foo {
                 let Some(self_) = deno_core::_ops::try_unwrap_cppgc_object::<
                     Foo,
                 >(&mut scope, args.this().into()) else {
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected Foo".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected Foo");
                     return 1;
                 };
                 let self_ = &*self_;
                 let result = {
                     let arg0 = args.get(0usize as i32);
                     let Some(arg0) = deno_core::_ops::to_u32_option(&arg0) else {
-                        let mut scope = unsafe {
-                            deno_core::v8::CallbackScope::new(info)
-                        };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                "expected u32".as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte_info(
+                            &info,
+                            "expected u32",
+                        );
                         return 1;
                     };
                     let arg0 = arg0 as _;
@@ -620,14 +575,10 @@ impl Foo {
                                 &*fast_api_callback_options,
                             )
                         };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                "expected Foo".as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte(
+                            &mut scope,
+                            "expected Foo",
+                        );
                         return unsafe { std::mem::zeroed() };
                     }
                 };
@@ -652,14 +603,7 @@ impl Foo {
                 let Some(self_) = deno_core::_ops::try_unwrap_cppgc_object::<
                     Foo,
                 >(&mut scope, args.this().into()) else {
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected Foo".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected Foo");
                     return 1;
                 };
                 let self_ = &*self_;
@@ -759,14 +703,7 @@ impl Foo {
                 let Some(self_) = deno_core::_ops::try_unwrap_cppgc_object::<
                     Foo,
                 >(&mut scope, args.this().into()) else {
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected Foo".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected Foo");
                     return 1;
                 };
                 let self_ = &*self_;
@@ -869,14 +806,7 @@ impl Foo {
                 let Some(self_) = deno_core::_ops::try_unwrap_cppgc_object::<
                     Foo,
                 >(&mut scope, args.this().into()) else {
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected Foo".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected Foo");
                     return 1;
                 };
                 let self_ = &*self_;
@@ -1062,14 +992,7 @@ impl Foo {
                 let Some(self_) = deno_core::_ops::try_unwrap_cppgc_object::<
                     Foo,
                 >(&mut scope, args.this().into()) else {
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected Foo".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected Foo");
                     return 1;
                 };
                 let self_ = &*self_;
diff --git a/ops/op2/test_cases/sync/op_state_ref.out b/ops/op2/test_cases/sync/op_state_ref.out
index d615e7e..5b1393d 100644
--- a/ops/op2/test_cases/sync/op_state_ref.out
+++ b/ops/op2/test_cases/sync/op_state_ref.out
@@ -393,15 +393,10 @@ const fn op_state_and_v8() -> ::deno_core::_ops::OpDecl {
                 let Ok(mut arg1) = deno_core::_ops::v8_try_convert::<
                     deno_core::v8::Function,
                 >(arg1) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected Function".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(
+                        &info,
+                        "expected Function",
+                    );
                     return 1;
                 };
                 let arg1 = deno_core::v8::Global::new(&mut scope, arg1);
@@ -572,14 +567,10 @@ const fn op_state_and_v8_local() -> ::deno_core::_ops::OpDecl {
                                 &*fast_api_callback_options,
                             )
                         };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                "expected Function".as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte(
+                            &mut scope,
+                            "expected Function",
+                        );
                         return unsafe { std::mem::zeroed() };
                     }
                 };
@@ -611,15 +602,10 @@ const fn op_state_and_v8_local() -> ::deno_core::_ops::OpDecl {
                 let Ok(mut arg1) = deno_core::_ops::v8_try_convert::<
                     deno_core::v8::Function,
                 >(arg1) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected Function".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(
+                        &info,
+                        "expected Function",
+                    );
                     return 1;
                 };
                 let arg1 = arg1;
diff --git a/ops/op2/test_cases/sync/serde_v8.out b/ops/op2/test_cases/sync/serde_v8.out
index 5b1a5e5..f801de0 100644
--- a/ops/op2/test_cases/sync/serde_v8.out
+++ b/ops/op2/test_cases/sync/serde_v8.out
@@ -44,13 +44,7 @@ pub const fn op_serde_v8() -> ::deno_core::_ops::OpDecl {
                 let arg0 = match deno_core::_ops::serde_v8_to_rust(&mut scope, arg0) {
                     Ok(t) => t,
                     Err(arg0_err) => {
-                        let msg = deno_core::v8::String::new(
-                                &mut scope,
-                                &format!("{}", deno_core::anyhow::Error::from(arg0_err)),
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_anyhow(&mut scope, arg0_err);
                         return 1;
                     }
                 };
@@ -65,13 +59,7 @@ pub const fn op_serde_v8() -> ::deno_core::_ops::OpDecl {
             ) {
                 Ok(v) => rv.set(v),
                 Err(rv_err) => {
-                    let msg = deno_core::v8::String::new(
-                            &mut scope,
-                            &format!("{}", deno_core::anyhow::Error::from(rv_err)),
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_anyhow(&mut scope, rv_err);
                     return 1;
                 }
             };
diff --git a/ops/op2/test_cases/sync/smi.out b/ops/op2/test_cases/sync/smi.out
index ca2697e..e022e9f 100644
--- a/ops/op2/test_cases/sync/smi.out
+++ b/ops/op2/test_cases/sync/smi.out
@@ -168,57 +168,25 @@ const fn op_smi_unsigned_return() -> ::deno_core::_ops::OpDecl {
             let result = {
                 let arg0 = args.get(0usize as i32);
                 let Some(arg0) = deno_core::_ops::to_i32_option(&arg0) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected i32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected i32");
                     return 1;
                 };
                 let arg0 = arg0 as _;
                 let arg1 = args.get(1usize as i32);
                 let Some(arg1) = deno_core::_ops::to_i32_option(&arg1) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected i32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected i32");
                     return 1;
                 };
                 let arg1 = arg1 as _;
                 let arg2 = args.get(2usize as i32);
                 let Some(arg2) = deno_core::_ops::to_i32_option(&arg2) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected i32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected i32");
                     return 1;
                 };
                 let arg2 = arg2 as _;
                 let arg3 = args.get(3usize as i32);
                 let Some(arg3) = deno_core::_ops::to_i32_option(&arg3) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected i32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected i32");
                     return 1;
                 };
                 let arg3 = arg3 as _;
@@ -447,57 +415,25 @@ const fn op_smi_signed_return() -> ::deno_core::_ops::OpDecl {
             let result = {
                 let arg0 = args.get(0usize as i32);
                 let Some(arg0) = deno_core::_ops::to_i32_option(&arg0) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected i32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected i32");
                     return 1;
                 };
                 let arg0 = arg0 as _;
                 let arg1 = args.get(1usize as i32);
                 let Some(arg1) = deno_core::_ops::to_i32_option(&arg1) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected i32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected i32");
                     return 1;
                 };
                 let arg1 = arg1 as _;
                 let arg2 = args.get(2usize as i32);
                 let Some(arg2) = deno_core::_ops::to_i32_option(&arg2) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected i32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected i32");
                     return 1;
                 };
                 let arg2 = arg2 as _;
                 let arg3 = args.get(3usize as i32);
                 let Some(arg3) = deno_core::_ops::to_i32_option(&arg3) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected i32".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected i32");
                     return 1;
                 };
                 let arg3 = arg3 as _;
@@ -602,17 +538,10 @@ const fn op_smi_option() -> ::deno_core::_ops::OpDecl {
                     None
                 } else {
                     let Some(arg0) = deno_core::_ops::to_i32_option(&arg0) else {
-                        let mut scope = unsafe {
-                            deno_core::v8::CallbackScope::new(info)
-                        };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                "expected i32".as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte_info(
+                            &info,
+                            "expected i32",
+                        );
                         return 1;
                     };
                     let arg0 = arg0 as _;
diff --git a/ops/op2/test_cases/sync/string_onebyte.out b/ops/op2/test_cases/sync/string_onebyte.out
index 4337b41..5fc6b04 100644
--- a/ops/op2/test_cases/sync/string_onebyte.out
+++ b/ops/op2/test_cases/sync/string_onebyte.out
@@ -127,17 +127,7 @@ const fn op_string_onebyte() -> ::deno_core::_ops::OpDecl {
                 let arg0 = match deno_core::_ops::to_cow_one_byte(&mut scope, &arg0) {
                     Ok(arg0) => arg0,
                     Err(arg0) => {
-                        let mut scope = unsafe {
-                            deno_core::v8::CallbackScope::new(info)
-                        };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                arg0.as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte_info(&info, arg0);
                         return 1;
                     }
                 };
diff --git a/ops/op2/test_cases/sync/string_option_return.out b/ops/op2/test_cases/sync/string_option_return.out
index 3a21c1d..db252bf 100644
--- a/ops/op2/test_cases/sync/string_option_return.out
+++ b/ops/op2/test_cases/sync/string_option_return.out
@@ -51,13 +51,7 @@ pub const fn op_string_return() -> ::deno_core::_ops::OpDecl {
             match deno_core::_ops::RustToV8Fallible::to_v8_fallible(result, &mut scope) {
                 Ok(v) => rv.set(v),
                 Err(rv_err) => {
-                    let msg = deno_core::v8::String::new(
-                            &mut scope,
-                            &format!("{}", deno_core::anyhow::Error::from(rv_err)),
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_anyhow(&mut scope, rv_err);
                     return 1;
                 }
             };
diff --git a/ops/op2/test_cases/sync/string_return.out b/ops/op2/test_cases/sync/string_return.out
index 9e5c8f9..6c443c6 100644
--- a/ops/op2/test_cases/sync/string_return.out
+++ b/ops/op2/test_cases/sync/string_return.out
@@ -40,13 +40,7 @@ pub const fn op_string_return() -> ::deno_core::_ops::OpDecl {
             match deno_core::_ops::RustToV8Fallible::to_v8_fallible(result, &mut scope) {
                 Ok(v) => rv.set(v),
                 Err(rv_err) => {
-                    let msg = deno_core::v8::String::new(
-                            &mut scope,
-                            &format!("{}", deno_core::anyhow::Error::from(rv_err)),
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_anyhow(&mut scope, rv_err);
                     return 1;
                 }
             };
@@ -138,13 +132,7 @@ pub const fn op_string_return_ref() -> ::deno_core::_ops::OpDecl {
             match deno_core::_ops::RustToV8Fallible::to_v8_fallible(result, &mut scope) {
                 Ok(v) => rv.set(v),
                 Err(rv_err) => {
-                    let msg = deno_core::v8::String::new(
-                            &mut scope,
-                            &format!("{}", deno_core::anyhow::Error::from(rv_err)),
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_anyhow(&mut scope, rv_err);
                     return 1;
                 }
             };
@@ -236,13 +224,7 @@ pub const fn op_string_return_cow() -> ::deno_core::_ops::OpDecl {
             match deno_core::_ops::RustToV8Fallible::to_v8_fallible(result, &mut scope) {
                 Ok(v) => rv.set(v),
                 Err(rv_err) => {
-                    let msg = deno_core::v8::String::new(
-                            &mut scope,
-                            &format!("{}", deno_core::anyhow::Error::from(rv_err)),
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_anyhow(&mut scope, rv_err);
                     return 1;
                 }
             };
diff --git a/ops/op2/test_cases/sync/to_v8.out b/ops/op2/test_cases/sync/to_v8.out
index 860fec8..f77b2f3 100644
--- a/ops/op2/test_cases/sync/to_v8.out
+++ b/ops/op2/test_cases/sync/to_v8.out
@@ -46,13 +46,7 @@ pub const fn op_to_v8_return() -> ::deno_core::_ops::OpDecl {
             ) {
                 Ok(v) => rv.set(v),
                 Err(rv_err) => {
-                    let msg = deno_core::v8::String::new(
-                            &mut scope,
-                            &format!("{}", deno_core::anyhow::Error::from(rv_err)),
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_anyhow(&mut scope, rv_err);
                     return 1;
                 }
             };
diff --git a/ops/op2/test_cases/sync/v8_global.out b/ops/op2/test_cases/sync/v8_global.out
index 602601d..c2a36ac 100644
--- a/ops/op2/test_cases/sync/v8_global.out
+++ b/ops/op2/test_cases/sync/v8_global.out
@@ -44,15 +44,7 @@ pub const fn op_global() -> ::deno_core::_ops::OpDecl {
                 let Ok(mut arg0) = deno_core::_ops::v8_try_convert::<
                     deno_core::v8::String,
                 >(arg0) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected String".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected String");
                     return 1;
                 };
                 let arg0 = deno_core::v8::Global::new(&mut scope, arg0);
diff --git a/ops/op2/test_cases/sync/v8_handlescope.out b/ops/op2/test_cases/sync/v8_handlescope.out
index 3c43265..b3b26d7 100644
--- a/ops/op2/test_cases/sync/v8_handlescope.out
+++ b/ops/op2/test_cases/sync/v8_handlescope.out
@@ -44,14 +44,7 @@ const fn op_handlescope() -> ::deno_core::_ops::OpDecl {
                 let Ok(mut arg1) = deno_core::_ops::v8_try_convert::<
                     deno_core::v8::String,
                 >(arg1) else {
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected String".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected String");
                     return 1;
                 };
                 let arg1 = arg1;
diff --git a/ops/op2/test_cases/sync/v8_lifetime.out b/ops/op2/test_cases/sync/v8_lifetime.out
index 4190933..79493e7 100644
--- a/ops/op2/test_cases/sync/v8_lifetime.out
+++ b/ops/op2/test_cases/sync/v8_lifetime.out
@@ -43,15 +43,7 @@ pub const fn op_v8_lifetime() -> ::deno_core::_ops::OpDecl {
                 let Ok(mut arg0) = deno_core::_ops::v8_try_convert::<
                     deno_core::v8::String,
                 >(arg0) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected String".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected String");
                     return 1;
                 };
                 let arg0 = arg0;
diff --git a/ops/op2/test_cases/sync/v8_ref_option.out b/ops/op2/test_cases/sync/v8_ref_option.out
index e63d845..8786194 100644
--- a/ops/op2/test_cases/sync/v8_ref_option.out
+++ b/ops/op2/test_cases/sync/v8_ref_option.out
@@ -114,14 +114,10 @@ pub const fn op_v8_lifetime() -> ::deno_core::_ops::OpDecl {
                                 &*fast_api_callback_options,
                             )
                         };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                "expected String".as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte(
+                            &mut scope,
+                            "expected String",
+                        );
                         return unsafe { std::mem::zeroed() };
                     }
                 };
@@ -138,14 +134,10 @@ pub const fn op_v8_lifetime() -> ::deno_core::_ops::OpDecl {
                                 &*fast_api_callback_options,
                             )
                         };
-                        let msg = deno_core::v8::String::new_from_one_byte(
-                                &mut scope,
-                                "expected String".as_bytes(),
-                                deno_core::v8::NewStringType::Normal,
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_one_byte(
+                            &mut scope,
+                            "expected String",
+                        );
                         return unsafe { std::mem::zeroed() };
                     }
                 };
@@ -173,15 +165,7 @@ pub const fn op_v8_lifetime() -> ::deno_core::_ops::OpDecl {
                 let Ok(mut arg0) = deno_core::_ops::v8_try_convert_option::<
                     deno_core::v8::String,
                 >(arg0) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected String".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected String");
                     return 1;
                 };
                 let arg0 = match &arg0 {
@@ -192,15 +176,7 @@ pub const fn op_v8_lifetime() -> ::deno_core::_ops::OpDecl {
                 let Ok(mut arg1) = deno_core::_ops::v8_try_convert_option::<
                     deno_core::v8::String,
                 >(arg1) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected String".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected String");
                     return 1;
                 };
                 let arg1 = match &arg1 {
diff --git a/ops/op2/test_cases/sync/v8_string.out b/ops/op2/test_cases/sync/v8_string.out
index 4e3f93b..bbd439c 100644
--- a/ops/op2/test_cases/sync/v8_string.out
+++ b/ops/op2/test_cases/sync/v8_string.out
@@ -43,15 +43,7 @@ const fn op_v8_string() -> ::deno_core::_ops::OpDecl {
                 let Ok(mut arg0) = deno_core::_ops::v8_try_convert::<
                     deno_core::v8::String,
                 >(arg0) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected String".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected String");
                     return 1;
                 };
                 let arg0 = &arg0;
@@ -59,15 +51,7 @@ const fn op_v8_string() -> ::deno_core::_ops::OpDecl {
                 let Ok(mut arg1) = deno_core::_ops::v8_try_convert::<
                     deno_core::v8::String,
                 >(arg1) else {
-                    let mut scope = unsafe { deno_core::v8::CallbackScope::new(info) };
-                    let msg = deno_core::v8::String::new_from_one_byte(
-                            &mut scope,
-                            "expected String".as_bytes(),
-                            deno_core::v8::NewStringType::Normal,
-                        )
-                        .unwrap();
-                    let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                    scope.throw_exception(exc);
+                    deno_core::_ops::throw_error_one_byte_info(&info, "expected String");
                     return 1;
                 };
                 let arg1 = arg1;
diff --git a/ops/op2/test_cases/sync/webidl.out b/ops/op2/test_cases/sync/webidl.out
index 525b3d5..805fca9 100644
--- a/ops/op2/test_cases/sync/webidl.out
+++ b/ops/op2/test_cases/sync/webidl.out
@@ -50,13 +50,7 @@ const fn op_webidl() -> ::deno_core::_ops::OpDecl {
                 ) {
                     Ok(t) => t,
                     Err(arg0_err) => {
-                        let msg = deno_core::v8::String::new(
-                                &mut scope,
-                                &format!("{}", deno_core::anyhow::Error::from(arg0_err)),
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_anyhow(&mut scope, arg0_err);
                         return 1;
                     }
                 };
@@ -70,13 +64,7 @@ const fn op_webidl() -> ::deno_core::_ops::OpDecl {
                 ) {
                     Ok(t) => t,
                     Err(arg1_err) => {
-                        let msg = deno_core::v8::String::new(
-                                &mut scope,
-                                &format!("{}", deno_core::anyhow::Error::from(arg1_err)),
-                            )
-                            .unwrap();
-                        let exc = deno_core::v8::Exception::type_error(&mut scope, msg);
-                        scope.throw_exception(exc);
+                        deno_core::_ops::throw_error_anyhow(&mut scope, arg1_err);
                         return 1;
                     }
                 };