Why is nodejs silently failing on an undeclared variable? It doesn't say anything, no stack trace, etc. This is the worst situation for debugging.
How do I get it to be noisier like any other language?
This is a little command-line utility written in nodejs. It's not a web app like most people are making. I'm fine with that. It's working as expected and I'm happily porting code over and everything works nice except when I make a typo and then it silently fails.
// Typo: should be var or const foo but I missed it and I want nodejs to error about it like any other language
foo = func();
I got a hint somewhere that promises are silencing errors like this. If so, why, and is there a workaround, preferably to make it die loudly.
Thanks
Shoot me. I missed logging the result of a promise rejection higher up. Once I put that in I started seeing the error and stack trace which was very helpful.
If I remember to log all rejection errors this will be fine.
The magic bit is that promises will use exceptions and send them to the rejection handler as the result object automatically.
This question+answer was helpful:
https://stackoverflow.com/a/46512164/3727869
Related
I recently completed making an asynchronous version for all the functions in a pure C API, wrapped with N-API to work with JS/TS as a nodejs addon.
The last problem I had to fix was making sure that C POSIX-style errors (ie, returned integer codes) were transferred correctly to the JS at the end of a worker's execution (with the corresponding string, for which we have both an enum of exceptions, and a list of error messages).
When thrown with napi_throw_error (as I did for the synchronous version of all our calls), within the napi_async_complete_callback, these exceptions were never caught at the JS level (I suppose it was because it was within a different async context; I saw online people having a similar problem with ajax). Instead, I opted to just construct my errors as napi_value types, and return these via napi_reject_deferred. This seemed to have the desired effect, of being caught properly when doing a try { await My_NapiWrapper_XYZ() } catch (ex) { ... }.
So I don't really have a problem to fix, but I AM intrigued. These napi_throw_error thrown errors do probably go somewhere. Though I have no idea where. Where should one look to catch an error thrown with napi_throw_error from a napi_async_complete_callback ? Can you give a code example ?
No, they don't go anywhere. It is a bug that I just opened with them:
https://github.com/nodejs/node/issues/41377
There is a general problem with handling exceptions in asynchronous callbacks. Normally, they cannot be catched and should lead to program termination but Node's developers have decided to try to keep it running when they can.
I have some really messy non-strict-compliant legacy code on javascript, running just fine on NodeJs 12, and I'm trying to abstract it away and test the overlaying, new layers of code using Jest/Mocks.
But when I try to run the tests I receive the following error:
Test suite failed to run
SyntaxError: /legacy-path/messy_legacy_code.js: Legacy octal literals are not allowed in strict mode (557:66)
at Parser._raise (node_modules/#babel/parser/src/parser/error.js:60:45)
I'm trying to mock it away first thing on my test code, but still get this error. It seems that Jest is trying to parse it with Babel; it really won't find any compliant code there... It just runs on Node, nothing else.
I already tried mocking the legacy code itself and also tried making a container to "abstract" it away and mocking the container. But it seems Jest still tries to read every bit of noncompliant code behind it.
My modern.test.js code looks like this:
jest.mock('../../../../legacy-path/messy-container')
const { ModernLayer } = require('../../../../modern-path/modern-module');
Any ideas on how I cant completely block Jest from trying to read this noncompliant code and just mock it away?
jest.mock('...') performs auto-mock, unless a mock from __mocks__ is used. It tries to process module exports and fails on syntax error.
The module should be manually mocked instead:
jest.mock('../../../../legacy-path/messy-container', () => ({ ModernLayer: ... }));
I'm using sinon to stub an instance of express-Request.
It looks something like this:
let req = sinon.createStubInstance(Request);
My method accepts req: Request but my IDE complains about me using SinonStubbedInstance<Request> rather than Request.
I've tried using req as Request but I still get a warning about 'may be a mistake' and that I should first cast to unknown and only then to Request.
I actually don't need anything from this parameter so I really just want to stub it quickly and easily.
When using it in the call to your method, just cast it:
myMethod(req as any);
I understand that this was posed 3 years ago, but since the only answer given is wrong, I feel obliged to comment, for someone else might benefit from it.
It's strongly discouraged to use as any and your compiler should complain about this (unless you have a very good reason not to, you should use strict compiler option).
Casting to unknown and then to your type seems unintuitive, but it is a cleaner way than casting to any. If you use any you might be better off not using typescript at all.
https://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html#any
Consider doing
let req: SinonStubbedInstance<Request> & Request = sinon.createStubInstance(Request);
instead.
P.S.: Also, the use of let seems suspicious (sure cannot use const?), but that's a different topic.
When I run my code with node 0.10.26, I'm getting an 'illegal access' error when using ES6 proxies. It doesn't happen with node 0.11.14
Any ideas how I can try to approach this? There's no stack trace.
I have a pretty convoluted proxy implementation, I've implemented the following methods:
get, set, has, hasOwn, delete, keys, enumerate, getOwnPropertyNames, getPropertyNames, getOwnPropertyDescriptor, getPropertyDescriptor
Is there a Proxy test suite set I can throw at it to see if I've implemented something incorrectly? Or any other way to see the source of the problem? I don't even know how to invoke half of the things I implemented :)
Any libraries that I can replace the Proxy object with? I think I saw one before but can't find it now.
EDIT: more details I forgot: It's not that there's no stack track, there's a stack trace from bluebird promise and it begins with Promise$_rejectPromises, which makes me think the error is related to this problem but I still don't know how find the source error with the problematic property.
So while looking for a Proxy replacement, I stumbled onto this thread, which says that this problem happens when something tries to use JSON.stringify() on the proxy.
I'm happy to say that implementing my own toJSON() method on the proxy object solved the problem.
Ahhh... so good to be back to 0.10.26
Using node-inspector, I'm unable to set breakpoint in the following node.js code. (Content of main.js)
(function() {
require('underscore');
var doSomething = function(callback) {
callback('doSomething Finished');
}
doSomething(function(x) {
console.log(x);
});
}).call(this);
I can easily set a breakpoint on line 2, line 4 or line 8, however no matter how hard I try the debugger won't let me set a break point on line 5 or line 9. To be clear, I'm using the following commands to run node-inspector
node --debug-brk main.js
node-inspector
I also tried to debug in web storm, however the issue persists. If I remove the line require('underscore');, then the problem immediately goes away and I'm able to set break point inside function body again. The problem also goes away if I remove the outermost closure function. It seems that the interaction between require and file level closure is screwing up the node debugging functionality. Has anyone experienced this problem themselves and / or knows any workarounds to be able to break inside function body?
EDIT: My node js version
Tony:~ $ node --version
v0.10.12
Tony:~ $
I ran exactly into the same issue with the same setup.
I've added a breakpoint after the definition of the target-function (that was the only place i could actually add a breakpoint). When the debugger reached that breakpoint and the function was actually defined, i was able to add breakpoints to the actual target-function...
This may not be the answer that you want to hear as it doesn't explain why you can't set any breakpoints, but I would simply remove your require statement from the closure and place it top-level. I would go even further and recommend that you don't use a closure like the one above at all.
The reason is that node uses its own module system, and unlike Javascript in the browser, declaring variables top-level does not pollute the global namespace. This is where require(...) comes in. So, you gain nothing by wrapping your code in an immediately invoked function (unless of course you want your module to be able to run both client side and server side).
I would guess that the reason that you are not able to set any breakpoints is that the V8 runtime is recognizing an unnecessary closure and then optimizing your code for you. The rewritten code may not have the correct source mapping and so breakpoints cannot be set.
So, two suggestions:
require calls are not like regular statements. They are more similar to import statements in Java and are handled specially by the compiler. They should always be top-level in a node file.
No need to wrap your code in an anonymous function when in Node.