neon-bindings / neon

Rust bindings for writing safe and fast native Node.js modules.
https://www.neon-bindings.com/
Apache License 2.0
8.05k stars 284 forks source link

thread '<unnamed>' panicked at 'assertion failed: `(left == right)`; left: `PendingException`, right: `Ok`' #959

Closed jimasun closed 1 year ago

jimasun commented 1 year ago

Hey, I have tried to make use a plugin which is using Neon and I am getting this along the way. I've already posed an issue with the plugin () and they suggested to raise an issue here.

This is the code where I am using the specific plugin - correct as verified by the creator of it.

process.env['RUST_BACKTRACE'] = 'full'
return minifyHtml.minify(Buffer.from(`
    <div class="lower-buttons">
        <span class="next primary button disabled">Next</span>
    </div>`))

The result output in the console.

thread '<unnamed>' panicked at 'assertion failed: `(left == right)`
  left: `PendingException`,
 right: `Ok`', C:\Users\runneradmin\.cargo\registry\src\github.com-1ecc6299db9ec823\neon-runtime-0.10.1\src\napi\error.rs:49:5
stack backtrace:
   0:     0x7fff51d21342 - napi_register_module_v1
   1:     0x7fff51d3245b - napi_register_module_v1
   2:     0x7fff51d1f8aa - napi_register_module_v1
   3:     0x7fff51d2108b - napi_register_module_v1
   4:     0x7fff51d230b9 - napi_register_module_v1
   5:     0x7fff51d22d3a - napi_register_module_v1
   6:     0x7fff51d23941 - napi_register_module_v1
   7:     0x7fff51d236cd - napi_register_module_v1
   8:     0x7fff51d21d6f - napi_register_module_v1
   9:     0x7fff51d23390 - napi_register_module_v1
  10:     0x7fff51d41475 - napi_register_module_v1
  11:     0x7fff51d317d4 - napi_register_module_v1
  12:     0x7fff51d403e0 - napi_register_module_v1
  13:     0x7fff51d19eb4 - napi_register_module_v1
  14:     0x7fff51c5114d - <unknown>
  15:     0x7fff51c52ced - napi_register_module_v1
  16:     0x7fff51c5225a - napi_register_module_v1
  17:     0x7fff51c52b93 - napi_register_module_v1
  18:     0x7ff6e4877100 - v8::internal::compiler::Instruction::Output
  19:     0x7ff6e528d35d - v8::internal::Builtins::code
  20:     0x7ff6e528cf69 - v8::internal::Builtins::code
  21:     0x7ff6e528d22c - v8::internal::Builtins::code
  22:     0x7ff6e528d090 - v8::internal::Builtins::code
  23:     0x7ff6e5371f81 - v8::internal::SetupIsolateDelegate::SetupHeap
  24:     0x7ff6e52f5894 - v8::internal::SetupIsolateDelegate::SetupHeap
  25:     0x7ff6e52f5894 - v8::internal::SetupIsolateDelegate::SetupHeap
  26:     0x7ff6e53299c3 - v8::internal::SetupIsolateDelegate::SetupHeap
  27:     0x7ff6e53c27b5 - v8::internal::SetupIsolateDelegate::SetupHeap
  28:     0x7ff6e531b0cc - v8::internal::SetupIsolateDelegate::SetupHeap
  29:     0x7ff6e52f3d9b - v8::internal::SetupIsolateDelegate::SetupHeap
  30:     0x7ff6e51be3ca - v8::internal::Execution::CallWasm
  31:     0x7ff6e51be4eb - v8::internal::Execution::CallWasm
  32:     0x7ff6e51bf29a - v8::internal::Execution::TryCallScript
  33:     0x7ff6e5197e6a - v8::internal::MicrotaskQueue::RunMicrotasks
  34:     0x7ff6e5197c0a - v8::internal::MicrotaskQueue::PerformCheckpointInternal
  35:     0x7ff6e48df288 - node::CallbackScope::~CallbackScope
  36:     0x7ff6e48df14e - node::CallbackScope::~CallbackScope
  37:     0x7ff6e4819fc7 - v8::base::CPU::has_fpu
  38:     0x7ff6e482ba51 - v8::internal::wasm::WasmCode::safepoint_table_offset
  39:     0x7ff6e4913c17 - uv_timer_stop
  40:     0x7ff6e49101bb - uv_async_send
  41:     0x7ff6e490f94c - uv_loop_init
  42:     0x7ff6e490faea - uv_run
  43:     0x7ff6e48deb15 - node::SpinEventLoop
  44:     0x7ff6e47e92c4 - std::basic_ios<char,std::char_traits<char> >::setstate
  45:     0x7ff6e486d058 - node::InitializeOncePerProcess
  46:     0x7ff6e486e895 - node::Start
  47:     0x7ff6e46874fc - CRYPTO_memcmp
  48:     0x7ff6e589fdd8 - v8::internal::compiler::ToString
  49:     0x7fff97d37614 - BaseThreadInitThunk
  50:     0x7fff986426a1 - RtlUserThreadStart
kjvalencik commented 1 year ago

@jimasun I can see how this stacktrace might make it look like a Neon issue, but, it isn't.

I see two problems. The first is the sample code is not using the minifyHtml method correctly. Reading the source, the options argument is a required field.

Try adding an empty object to your code.

return minifyHtml.minify(Buffer.from(`
    <div class="lower-buttons">
        <span class="next primary button disabled">Next</span>
    </div>`), {})

Secondly, it looks like this library is mishandling the Throw error. When this is present, a library should typically return early because it's invalid to call almost all Neon/Node APIs while in a throwing state.

However, the library is attempting to throw a new error after failing to get the original here:

https://github.com/wilsonzlin/minify-html/blob/c0f7ac99e1684ed4d6ffdb0657854c8e9a65329a/nodejs/src/lib.rs#L9

There are a few different ways to handle this, but, one way is to catch the exception prior to re-throwing:

    let Ok(opt) = cx.try_catch(|cx| cx.argument::<JsObject>(1)) else {
      return cx.throw_type_error("the second argument is not an object");
    };
jimasun commented 1 year ago

Thank you for looking into it. The code was fixed on the plugin side.