Issue with `serialport` in dev
Environment
nitropack: latest compatibilityDate: "2025-03-04"
Node.js: v20.18.3
Reproduction
import { Buffer } from 'node:buffer'
import { SerialPort } from 'serialport'
export default defineNitroPlugin(() => {
const port = new SerialPort({
path: 'COM3',
baudRate: 115200,
})
port
.on('data', (data) => {
console.log((data as Buffer).toString('utf-8'))
})
port.write(Buffer.from('Hi me!'))
})
When receive any data from serial (whatever using plugin or eventHandler), it will panic.
Describe the bug
When receiving data by using serialport, we have a error:
FATAL ERROR: HandleScope::HandleScope Entering the V8 API without proper locking in place
Error details
FATAL ERROR: HandleScope::HandleScope Entering the V8 API without proper locking in place
----- Native stack trace -----
1: 00007FF6BA90738B node::SetCppgcReference+19771
2: 00007FF6BA877DF9 node::OnFatalError+265
3: 00007FF6BB2E5929 v8::HandleScope::Initialize+137
4: 00007FF6BB2CDC2E v8::HandleScope::HandleScope+14
5: 00007FF6BA8CF99A napi_open_handle_scope+154
6: 00007FFA3677A0E0 napi_register_module_v1+9744
7: 00007FF6BA96CD2B uv_update_time+491
8: 00007FF6BA96C8A4 uv_run+900
9: 00007FF6BA93D7A5 node::SpinEventLoop+405
10: 00007FF6BA824392 OSSL_STORE_LOADER_get0_description+153698
11: 00007FF6BA8BB26D node::Start+4957
12: 00007FF6BA8B9F40 node::Start+48
13: 00007FF6BA66D9BC AES_cbc_encrypt+151532
14: 00007FF6BBB0848C inflateValidate+19196
15: 00007FFA6BC97374 BaseThreadInitThunk+20
16: 00007FFA6D13CC91 RtlUserThreadStart+33
FATAL ERROR: v8::HandleScope::CreateHandle() Cannot create a handle without a HandleScope
----- Native stack trace -----
1: 00007FF6BA90738B void __cdecl node::SetCppgcReference(class v8::Isolate * __ptr64,class v8::Local<class v8::Object>,void * __ptr64)+19771
2: 00007FF6BA877DF9 void __cdecl node::OnFatalError(char const * __ptr64,char const * __ptr64)+265
3: 00007FF6BB2F162B public: void __cdecl v8::FunctionTemplate::RemovePrototype(void) __ptr64+331
4: 00007FF6BB187896 public: struct v8::WrapperDescriptor __cdecl v8::CppHeap::wrapper_descriptor(void)const __ptr64+64918
5: 00007FF6BB2CDB24 public: __cdecl v8::EscapableHandleScope::EscapableHandleScope(class v8::Isolate * __ptr64) __ptr64+52
6: 00007FF6BA876E69 DSA_meth_get_flags+89289
7: 00007FF6BA9072A2 void __cdecl node::SetCppgcReference(class v8::Isolate * __ptr64,class v8::Local<class v8::Object>,void * __ptr64)+19538
8: 00007FF6BA877E0B void __cdecl node::OnFatalError(char const * __ptr64,char const * __ptr64)+283
9: 00007FF6BB2E5929 protected: void __cdecl v8::HandleScope::Initialize(class v8::Isolate * __ptr64) __ptr64+137
11: 00007FF6BA8CF99A napi_open_handle_scope+154
12: 00007FFA3677A0E0 napi_register_module_v1+9744
13: 00007FF6BA96CD2B uv_update_time+491
14: 00007FF6BA96C8A4 uv_run+900
15: 00007FF6BA93D7A5 class v8::Maybe<int> __cdecl node::SpinEventLoop(class node::Environment * __ptr64)+405
16: 00007FF6BA824392 X509_STORE_get_cleanup+153698
17: 00007FF6BA8BB26D int __cdecl node::Start(int,char * __ptr64 * __ptr64 const)+4957
18: 00007FF6BA8B9F40 int __cdecl node::Start(int,char * __ptr64 * __ptr64 const)+48
19: 00007FF6BA66D9BC AES_cbc_encrypt+151532
20: 00007FF6BBB0848C inflateValidate+19196
21: 00007FFA6BC97374 BaseThreadInitThunk+20
22: 00007FFA6D13CC91 RtlUserThreadStart+33
ELIFECYCLE Command failed with exit code 134.
Additional context
serialport is a js lib based on nodejs, which is usually used for serial communication.
The repro code above works well if using node xxx.mjs to boot it. So I guess maybe I cannot use serialport or even Node.js in Nitro directly like this?
It seems an issue with Node.js worker threads (that runs isolated code) and serialport library. (I expect nitro production build works)
Can you try using devHandlers ?
As your expect, nitro production build and devHandlers both work. Is that possible to make it work without devHandlers?
We need to investigate what is the issue with serialport or Node.js/v8.
We might support alternative runner for Nitro dev server (to use full Node.js process which is slower) in future releases but nothing is immediately fixable.
Thanks for the quick feedback!
but nothing is immediately fixable
That said, I'm still glad to know that this will be improved in the future. At least for now this isn't completely unusable.
// routes/foo.ts
export default defineEventHandler()
// nitro.config
import foo from './src/routes/foo'
devHandlers: [
{
route: '/'
handler: foo
}
]
This works as expected, the problem is that then routes/foo.ts can't use auto-improt. This is not unacceptable, but I'd like to be able to turn off code hints for auto-import in this file, I wonder if there's a setting for that?
// routes/foo.ts Maybe like:
// ts-disable-something
import { defineEventHandler } from 'h3'
export default defineEventHandler()
We have the same issue using confluentinc/confluent-kafka-javascript which uses librdkafka under the hood.
The serialport cannot work in worker threads, as reported here: https://github.com/serialport/node-serialport/issues/2748
We might support alternative runner for Nitro dev server (to use full Node.js process which is slower) in future releases but nothing is immediately fixable.
Until this is supported, you might need to track serialport's progress on this issue.
Hey! I'm running into a similar issue with JCMais/node-libcurl Could this be happening because nitro encapsulates routes inside worker processes??
FATAL ERROR: v8::HandleScope::CreateHandle() Cannot create a handle without a HandleScope
----- Native stack trace -----
1: 0xe19ca5 node::OnFatalError(char const*, char const*) [node]
2: 0x123f996 v8::Utils::ReportApiFailure(char const*, char const*) [node]
3: 0x13ec8ba v8::internal::HandleScope::Extend(v8::internal::Isolate*) [node]
4: 0x1254da0 v8::Object::GetCreationContextChecked() [node]
5: 0xe720ba node::MakeCallback(v8::Isolate*, v8::Local<v8::Object>, v8::Local<v8::Function>, int, v8::Local<v8::Value>*, node::async_context) [node]
6: 0x7efb54c42016 NodeLibcurl::Easy::OnHeader(char*, unsigned long, unsigned long)
....