-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Allow catching JavaScript exceptions from C++ #11496
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Sorry I didn't fully read your plan.. I see that you are proposing the same thing.. deleting my first comment. |
@RReverser Are you talking about new wasm EH proposal or the existing Emscripten EH? |
@aheejin Those are implementation details that are kind of orthogonal to my proposal; the proposal is mainly about catching exceptions on JS side and rethrowing them as JS value handles with Embind on C++ side. How C++ exceptions are implemented shouldn't matter in this context. |
I badly need this to catch errors related to Fetch API since emscripten's own Fetch API is callback based, and I prefer my own version with val's await() I'm currently using ugly hacky workaround to catch exceptions. |
How's the progress of this feature? I want to catch exception by JSON.parse |
I don't think there was any but I'm really hoping it will get picked someday. Offtop: didn't realise it's been 1.5 years since I've submitted it 🤯 |
I'm not sure what this is proposing. In the original post,
In #11496 (comment),
So the former seems to be asking for the capability that we catch JS exceptions from C++. But the latter says "catching exceptions on JS side". Can you provide some example code? And is this possibly related to recent discussions in #6330? |
Sorry for the confusion. The former is for what we'd want feature-wise (what it would look like for the user == catching JS exception from C++), whereas in the latter I was proposing how it could be implemented (implementation detail == catching JS exception from JS, storing it as The example in issue description is still what I'd want it to look like for the user. |
Having a way to catch JavaScript exceptions in C++ would be very helpful. If an unexpected JavaScript exception occurs in the program's main loop C++ thread, the thread dies and it appears that the app has frozen. Trying to explain how to use the developer console to users to get the error message is not an option. Currently I have to hack worker.js file to at least add an alert that the app has failed. I would really like a way to contain exceptions in the thread in C++ and possibly keep the thread alive. |
Any exceptions that occurs in a pthread (worker.js) should get propagated back to the main thread and cause the application to abort. If any thread dies the whole application should die/abort. If you install an If you are not seeing that behaviour then perhaps we have a bug. Can you explain a little more about your situation. |
The problem is that there is no way to capture (and contain) some exceptions (see #16548) in the pthread. The pthead terminates, so the app dies. When working with a large file on Safari we cannot gracefully fail with an error message when Safari hits the memory limit. |
Can you not catch the error on the main page via the |
Probably, but by then it is way too late. The app's main pthread is terminated. Not being able to detect a "disk full" in the thread is the problem. Because we cannot catch JS exceptions in C++, the exception cannot be contained in the thread that triggered it. Try creating a thread with the following code:
The thread terminates when f.write fails and the exception is never caught within the thread. |
As you pointed out, catching JS exceptions from C++ is not yet supported. We're planning to work on it but it may not be very soon. Is there a way from C++ to check if a JS exception has occurred? If so, in the meantime, if what you want is to print some error messages and abort, does this workaround work? struct SomeObject {
~SomeObject() {
if (JS exception occurred) {
Print some error message
abort();
}
}
};
int main() {
SomeObject o;
Do something that can throw JS exceptions
} |
Unfortunately the destructor isn't called. The moment the range error occurs in f.write, the thread terminates. |
The thing you are trying to catch is an "out of memory" during malloc, right? The FS layer may need some modification to check all it allocation site. Also you would need to make sure you build with In short, trying to catch and recover from out of memory errors is non-trivial... are you sure this is something you really need? What do you plan to do in such cases? |
No. If the loop was:
The memory error is caught and the thread continues to run. There is no problem (aside from a massive memory leak :) ). The problem is that f.write fails in a way that cannot be caught, due to an unhandled JS exception, possibly in the FS layer as you mentioned. Having the app fail uncontrollably when trying to save data is a serious problem. If the failure could be caught, then the app could offer alternatives, such as sending the data to cloud storage or over the network. |
Out of interest, how do you catch the failure of In general do you catch all What would you think about having |
The problem isn't really a memory allocation error. It is a problem in the file system not catching a "disk full" exception and handling that in an appropriate way. The exception goes unhandled. So Having a way to handle JS exceptions in C++ would give C++ developers a way of hardening the app from such failures. A simple |
Does int main() {
EM_ASM({
try {
real_main();
} catch (e) {
Handle the error gracefully
}
});
} |
Here is a complete sample. There is no way to get to the "Success!" message when a thread is used. Writing a large file requiring slow encoding on a thread to keep the browser responsive is a very common use scenario. In my case it is critical to keep the thread alive by containing the error within the thread. Emscripten always kills the thread in this sample.
|
It sounds like the immediate problem will be fixed by having I'm rather surprised that |
Somewhat wider version of #11434, but applicable to synchronous functions as well: right now, even with exception handling enabled, there is no way to catch an exception from JavaScript call in C++ and extract its properties.
This means that things like DOMException can't be gracefully handled on C++ side or e.g. when integrating with C libraries where you want to convert different kinds of DOMException into different error codes.
I propose to make it possible to catch any JS exceptions and rethrow them on C++ side with Embind, so that things like
would work and return a JS handle to the caught exception.
The text was updated successfully, but these errors were encountered: