What does `napi_throw_error` do when called from an asynchronous N-API addon's `napi_async_complete_callback`? - node.js

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.

Related

Why is nodejs silently failing on an undeclared variable?

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

How to check if ID3D12GraphicsCommandList has been closed?

I'm learning DirectX12 and writing some utility classes to encapsulate functionality. Right now I'm working on mechanism for pooling CommandLists.
The pool assumes all command lists are closed. I wanted to validate that during inserting to the pool, but I can't manage to check it. From MSDN:
Returns S_OK if successful; otherwise, returns one of the following
values:
E_FAIL if the command list has already been closed, or an invalid API was called during command list recording.
Which is precisely what I'm looking for, but when I call ID3D12GraphicsCommandList::Close() to validate, it throws exception in KernelBase.dll. It looks really bizarre to me. Is this specification incompliance?
//EDIT: I cannot catch the exception, even with catch(...). It tells me maybe something may be wrong with my setup, but everything else is working for me.

Cant figure out what these errors happening on my webstore? Anyone help, posting the error content

enter image description here
No idea whats going with these errors code, i dont understand why is it saying anonymous and its giving me security concerns
Strictly speaking, those are warnings (not errors). Nothing is broken, but some things may be running sub-optimally. The alerts are noting that the code on your site is preloading a number of assets but not using them right away. This may indicate that your site is unnecessarily using priority resources to bring those resources in.
Beneath the warning message, you are seeing what is known as a "call stack" - it's the chain of functions that have been called to get to the point that resulted in that warning message. There are two kinds of functions in Javascript: named functions and anonymous functions.
Named functions are what you might normally think of as a function. You declare it with something like:
function doSomething(parameter){
// Some awesome code here
}
And later call it as:
doSomething(some_input);
However, in Javascript we can also create un-named, aka anonymous, functions in-line. This is often done for 'callback' functions, or functions that serve as a part B to the main function's part A, especially when part A does something asynchronously.
For example, if we want to fetch a file and then do something with it once it loads, we would make an asynchronous file call and then run our callback function once it loads. If we're using a library like jQuery as a helper to make that call, our code might look something like this:
function getPageAndDoStuff(url, callback){
jQuery.get(url, callback)
}
// We can declare a named function to do our stuff...
function justLogIt(html){
console.log(html);
}
getPageAndDoStuff('/cart', justLogIt);
Alternatively:
// We can just declare an inline anonymous function to do that
getPageAndDoStuff('/cart', function(html){
console.log(html);
})
The latter is a common design pattern for many types of tasks, but you'll note that the function we pass around doesn't have a name. When something happens and we look at the call stack to see the order of functions that have been called to get us to that point, what name would we print? Each unnamed function in our chain is simply called "(anonymous)"
Going back to your posted image, there is nothing in what you're showing that indicates a cause for serious concern. The script file 'rocket-loader' is possibly pre-loading a few assets that it doesn't need to, so you may be able to boost your site's performance by tweaking whatever parameters 'rocket-loader' uses to be more selective in what you are pre-loading.

Catching Haskell exceptions with gi-gtk and Reactive Banana

My application is bug-free, of course, but just in case it contains any bottom values I want to put in a generic exception catcher which will at least pop up a message box to tell the user what kind of bug to report. Because I'm using gi-gtk I figured that any exceptions after initialisation will happen from inside the Gtk.main function, so the end of my main function looks looks something like this:
let executeProgram =
catch Gtk.main $ \e -> do
reportThisBugDialog $ show (e :: SomeException)
-- Code here to try to recover to a known good state
executeProgram
executeProgram
I'm also using Reactive Banana in case that is relevant, but this is outside the FRP code.
However this doesn't capture any exceptions. I put error "Test Exception" in the handler for "Help About", and my program just exited with a message printed to the console (which my users will not see of course).
How do I catch exceptions that occur inside my code when it is reacting to GTK signals?
There is similar question here (though it is not specific to gi-gtk, so is a bit more general)t. Also I'd recommend this post.
Basically, haskell exceptions can't pass haskell/C border. Simply because C doesn't know anything about haskell exceptions.
In your case, Gtk.main runs gtk event loop, which is implemented in C, and callbacks are implemented in haskell. When callback throws haskell exception, it has to go through gtk event loop in order to reach executeProgram function. But it is impossible for the reason stated above.
I'm afraid, the solution is to catch all exceptions inside each callback. In your case, you probably can write a wrapper over on function from gi-gtk, which will catch all exceptions and show the bug dialog.

Should async function never ever throw?

I wrote a library with a number of async functions.
A SYNCHRONOUS helper function throws an error if one of the parameters is plain wrong:
proto.makeParameters= function( filters ){
default:
throw( new Error("Field type unknown: " + fieldObject.type ) );
break;
}
In my async functions, when I use it, I have:
proto.someAsyncFunction = function( cb ){
// Run the query
try {
var parameters = this.makeParameters( filters );
} catch( e ){
return cb( e );
}
}
So:
Is it good practice that asyncfunctions should never ever throw? (Like I did)
Right now, I am catching ALL errors. Shall I e more choosy? Maybe make up an error type and just check for that? If so, what should I do in either case?
Your assumptions on the async code are correct. See this post by Isaac Schlueter himself on the topic:
The pattern in node is that sync methods throw, and async methods pass
the error as the first argument to the callback. If the first
argument to your callback is falsey (usually null or undefined), then
all is well with the world.
http://groups.google.com/forum/#!msg/nodejs/W9UVJCKcJ7Q/rzseRbourCUJ
Is it good practice that async functions should never ever throw? (Like I did)
async functions, of course, will throw exceptions whenever we like it not, simply because of the software imperfection. So throwing custom exception is completely fine but what is important is how to correctly catch them.
The problem is that differently from sync code the stack of the async exception may not be available. So when the exception occurs, it is not always possible to say where to return the control and where is the handler. node.js has two methods of specifying what to do when the exception in asynchronous code occurs: process uncaughtException and domains.
As you see, dealing of the exceptions in async code is tricky so throwing an exception should be considered as a last option. If the function just returns status of the operation it is not an exception.
It seems for me that in the provided code fragment the exception is thrown correctly because it indicates that the method was called improperly and cannot do its job. In other words, the error is permanent. This indicates serious flaw in the application that should be fixed. But if the function cannot create a parameter for some temporary reason that can be fixed without modifying the application, then returning the status is more appropriate choice.

Resources