0

Using AngularJs v1.5.7, I'm having quite some trouble trying to log the exception.
The issue seem to be with the type of the exception.
This object is somehow not a normal object with properties.
Here is a code sample with what I have attempted so far and the result for each attempts.

MyApp.config(['$provide', function ($provide)
{
    $provide.decorator('$exceptionHandler', ['$delegate', 'logsService', function ($delegate, logsService)
    {

        return function (exception, cause)
        {
            $delegate(exception, cause);
            try
            {

                //Attempt #1 : throw because exception isn't an object.
                logsService.addLog(exception);

                //Attempt #2 : Log the hardcoded object with both properties
                logsService.addLog({a:'Some test', b:'Ok'});

                //Attempt #3 : log an empty object because exception has no property 
                var log = {};
                for (var property in exception)
                {
                    if (object.hasOwnProperty(property))
                    {
                        log[property] = exception[property];
                    }
                }
                logsService.addLog(log);

                //Attempt #4 : Log the message, but doesn't log all possible properties that exception could have.  
                logsService.addLog({ message: exception.message});
            }
            catch (ignore) { }
        };
    }]);
}]);

N.B : I can't change the logsService.
So far, I didn't find anything about this on google.

Why does exception has no properties and how to work around this limitation?

Edit :

I think I've pinpoint a little more the issue. The exception object is probably not clean and have functions or others things that can't be cloned. This give the following error in the log service.

DataCloneError: Failed to execute 'put' on 'IDBObjectStore'`

Source

Error and Function objects cannot be duplicated by the structured clone algorithm; attempting to do so will throw a DATA_CLONE_ERR exception.

    //Attempt #5 : log an empty object because exception has no property.
    var cleanedException = JSON.parse(angular.toJson(exception));
    logsService.addLog(cleanedException);

Is is what the exception show when inspecting it in the watch. enter image description here

Community
  • 1
  • 1
AXMIM
  • 2,424
  • 1
  • 20
  • 38
  • See [AngularJS $exceptionHandler Service API Reference - Example](https://docs.angularjs.org/api/ng/service/$exceptionHandler#example-). It shows how to overwrite the default `$exceptionHandler`. The default implementation simply delegates to `$log.error` which logs it into the browser console. – georgeawg Jul 26 '19 at 23:30
  • @georgeawg Like you stated, I've tryied overwriting the default implementation but the exception still doesn't have properties and the problem remained the exact same. – AXMIM Jul 27 '19 at 19:47
  • @georgeawg Error is fine, I've added an image what the inspector show about it. But I think the issue is about `Error and Function objects cannot be duplicated by the structured clone algorithm; attempting to do so will throw a DATA_CLONE_ERR exception.` – AXMIM Jul 27 '19 at 20:08

2 Answers2

0

To copy an Error object to a plain JavaScript object:

e = new Error("Example");

plain = { message: e.message, stack: e.stack };

console.log(plain);

Then it can be cloned for a Web Worker.

georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • Thanks, I could have done this from the start, but refrained to do so because I've seen cases when there is more properties than just `error` and `message`. My code doesn't need to know what is inside the exception, it just need to log whatever is inside it. – AXMIM Jul 27 '19 at 20:43
0

This issue is caused because error can't be cloned as stated here which is quite suttle.

Error and Function objects cannot be duplicated by the structured clone algorithm; attempting to do so will throw a DATA_CLONE_ERR exception.

So others have ran into related issue Is it not possible to stringify an Error using JSON.stringify? and they found a work around using Object.getOwnPropertyNames. Object.getOwnPropertyNames has been the way to go for me because all possible properties will be logged.

     //Attempt #6: Log all properties
     var cleanedException = JSON.parse(JSON.stringify(exception, Object.getOwnPropertyNames(exception)));
     logsService.addLog(cleanedException);
AXMIM
  • 2,424
  • 1
  • 20
  • 38