I've been working with Zone.js and I want to set up logging for any uncaught exceptions. I could set up an error handler, like so:
window.onerror = function(e) {
//send an error report to the server
}
But this won't work if an exception is thrown inside a Promise. The nice thing about the Zone error handler is that it hooks into Promises and does fire for exceptions in them, but I can't find a way to actually override or add an error handler after the Zone has been created aside from overriding a bunch of private fields on the Zone.
Is there an actual API for a Zone that I can use to update the error handler, or do I have to change the polyfill where the root Zone is constructed or overwrite private fields or something similar?
for promise uncaught promise error, from zone.js 0.78, you can use this API.
https://github.com/angular/zone.js/pull/627
window.addEventListener("unhandledrejection", function (event) {
console.warn("WARNING: Unhandled promise rejection. Shame on you! Reason: "
+ event.reason);
});
window.addEventListener("rejectionhandled", function (event) {
console.log("Promise rejected! Reason: " + reason);
});
You could try something like this:
<html>
<head>
<script src="https://unpkg.com/zone.js?main=browser"></script>
<script>
Zone.current.fork({
onHandleError: function(parentZoneDelegate, currentZone, targetZone, error) {
console.log("Error handled by zone: " + error);
}
}).run(function () {
setTimeout(function () {
console.log("In zone setTimeout")
throw new Error("Throw in zone setTimeout");
}, 0);
console.log("Directly in zone");
});
</script>
</head>
<body>
</body>
</html>
Which would catch the exception in the custom handler specified by onHandleError
and yield output like this:
Directly in zone (test1.html:14)
In zone setTimeout (test1.html:11 )
Error handled by zone: Error: Throw in zone setTimeout (test1.html:7)
However it seems it does not work if exceptions are thrown directly in the zone. I have filed and issue about this.
You have to use runGuarded
method instead of run
on Zone if you want to handle all types of unhandled exceptions (in simple zones, in setTimeouts or in Promises, etc.)
Here is a sample code to do that:
Zone.current.fork({
name: 'MyGlobalErrorLoggerZone',
onHandleError: function(parentZoneDelegate, currentZone, targetZone, error){
console.log(error);
// send it to server here.
}
})
.runGuarded(function(){
// your application code here...
// handles errors inside promises
new Promise(function(resolve, reject){
reject('Rejecting: Some Error');
});
console.log('Running in Zone...', Zone.current.name);
// handles errors inside timeouts/intervals
setTimeout(function(){
console.log('after 1 sec', Zone.current.name);
throw new Error('This is an error. Make your self log me please.');
}, 1000);
// Handles errors throw directly in zone too.
throw new Error('oops, one more error');
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With