If I eval a script with intentionally made mistakes I get an error log in console with a script reference link at the right side. For instance, here is the script:
my_script = 'const a = 2;\nconst b = a 2;';
eval(my_script)
Here is the console screenshot after execution:
At the right corner you see this lovely script reference link that I adore and appreciate very much. The main reason for this appreciation is that by clicking on it I can view the script that caused error and even look at the exact place where the error occurred:
But if I want to have some additional logic to happen upon error and therefore I add try/catch statement with this logic, I lose script reference and my lovely script reference link doesn't lead to my initial script anymore. Instead it leads to eval code itself. Here is the new script:
my_script = 'const a = 2;\nconst b = a 2;';
try {
eval(my_script)
} catch (e) {
// first we do some additional logic like error type checking and etc
// then we just log error so a user could view the erroneous script, the exact position of error and maybe make amends
console.error(e)
}
Here is what I see after executing it:
As you can see, the trace consists only of 2 records - the initial code and the eval code, but the first one is not clickable. And here is what I see after clicking the only available script reference link:
The debugger now shows me the eval code itself, not the initial script that is being evaluated
How to preserve script reference when evaluating an arbitrary script inside try/catch statement? Is there a way to catch eval error and still be able to view the actual script in chrome debugger?
In chromium based browsers, the argument of eval
is put in a new file by the developer tools (through VM I guess). Same happens with JSON.parse
, and other similar functions. This new file is called VM, from "virtual machine" followed by some digits.
When you catch the error coming from eval
, you override the default reportError
that the browser has, as @kaiido is pointing. If you inspect the error, specially if you inspect the stack, you can see that, originally, you don't have reference to the VM file. This is because, as the docs of reportError
says, you are preventing the error to be thrown, again, by other handlers:
This ensures that an exception in one callback will not prevent others from being handled, while at the same time ensuring that stack trace information is still readily available for debugging at the top level.
This is why, if you throw the error again in the catch
of the promise (as @damzaky says), the error is shown as you wanted, handled by the default dev tools handler for errors. But apparently this is not happening with try...catch
blocks, but this is something I haven't figured out.