Giter Site home page Giter Site logo

exceptionless / exceptionless.javascript Goto Github PK

View Code? Open in Web Editor NEW
60.0 9.0 24.0 11.97 MB

Exceptionless JavaScript client

Home Page: http://exceptionless.com

License: Apache License 2.0

JavaScript 8.07% TypeScript 88.57% HTML 1.57% CSS 0.39% Vue 0.67% Svelte 0.73%
javascript angular unhandled-exceptions crash-reporting exception-handler exceptionless logging logging-library node nodejs

exceptionless.javascript's People

Contributors

csantero avatar dependabot[bot] avatar ejsmith avatar ethianwong avatar frankebersoll avatar mkalpana avatar niemyjski avatar polluterofminds avatar srijken avatar tekmaven avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

exceptionless.javascript's Issues

Promises: Unhandled rejections

One big issue with exception handling in JavaScript is Promises: When you don't explicitly handle an error using a rejection callback, most Promise libraries provide global events like Promise.onPossiblyUnhandledRejection (bluebird.js), Q.getUnhandledReasons (Q.js) or process.on('unhandledRejection) (Node.js). Not subscribing to those events when using Promises probably contributes to many programmer errors staying unnoticed, as the application won't neccessarily terminate.

It would be cool if Exceptionless.js checked for the existence of such modules and events and created handlers that automatically submit the exceptions. While we do that, we should refactor all global exception handlers into implementations of an interface that can be added to the configuration like plugins.

Name proposals:

  • IGlobalExceptionHandler
  • IExceptionHook
  • IExceptionSource

Error when using createLog in IE11

This was introduced with #22, take care that whatever that PR fixed doesn't get reintroduced by fixing this.

TypeError: Accessing the 'caller' property of a function or arguments object is not allowed in strict mode
at ExceptionlessClient.prototype.createLog() in https://cdn.rawgit.com/exceptionless/Exceptionless.JavaScript/v1.0.1/dist/exceptionless.js:line 2082:col 13
at S() in https://****.****.net/scripts/app.min.js:line 23:col 2530
at C() in https://****.****.net/scripts/app.min.js:line 23:col 1023
at c() in https://****.****.net/scripts/app.min.js:line 29:col 20751
at Anonymous function() in https://****.****.net/scripts/app.min.js:line 29:col 29486
at Anonymous function() in https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js:line 118:col 324
at n.prototype.$eval() in https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js:line 132:col 441
at n.prototype.$digest() in https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js:line 129:col 455
at n.prototype.$apply() in https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js:line 133:col 234
at g() in https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js:line 87:col 374
at K() in https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js:line 91:col 448
at z.onload() in https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js:line 92:col 462

Repeat send options HTTP method

When I use exceptionless.js on my page, I found a behavior below this

request

it seems to check server health or something every 2 minutes.
so it 's possible to close these requests from client side?

Unhandled exceptions aren't logged automatically

The Readme claims:

Once configured, Exceptionless.js will automatically submit any unhandled exceptions that happen in your application to the Exceptionless server.

For me it looks like this isn't the case. Here's a reduced test case in which I would expect to get three exceptions logged to the server, which doesn't happen:

<!DOCTYPE html>

<html>
<head>
    <title>Exceptionless test</title>
    <script src="https://raw.githubusercontent.com/exceptionless/Exceptionless.JavaScript/master/dist/exceptionless.js"></script>
    <script>
        var exceptionlessClient = new exceptionless.ExceptionlessClient( {
            apiKey: 'YOUR_API_KEY',
            serverUrl: 'YOUR_SERVER',
        } );
  </script>
</head>

<body>
    <button type="button">Throw exception, plz.</button>

    <script>
        // This isn't reported to the Exceptionless server:
        window.setTimeout(
            function() { throw new Error( 'Test error in setTimeout handler' ); },
            1000
        );

        // This isn't either:
        document.getElementsByTagName( 'button' )[0].addEventListener(
            'click',
            function() { throw new Error( 'Test error in click handler' ); },
            false
        );

        // No report, again…
        (function xhrExceptionTest() {
            var myRequest = new XMLHttpRequest();
            myRequest.open( 'GET', 'http://httpstat.us/500', true );
            myRequest.onreadystatechange = function() {
                if ( myRequest.readyState === myRequest.DONE && myRequest.status !== 200 ) {
                    throw new Error( 'Test error in XHR handler' );
                }
            };
            myRequest.send( null );
        }());

        // This works:
        // exceptionlessClient.submitException( new Error( 'submitException' ) );
    </script>
</body>
</html>

I tested with Firefox 46, Chrome 50 and Safari 9.1 on Mac OS 10.11.4.

request data have a mistake

if i use this function

client.submitLog('app.logger', 'submitLog', 'Info')

the request info like this :

[
    {
        "date": "2016-11-09T14:26:39.742Z",
        "type": "log",
        "source": "app.logger",
        "message": "submitLog",
        "data": {
            "@level": "Info",
            "@environment": {
                "processor_count": 4,
                "total_physical_memory": 8485175296,
                "available_physical_memory": 4277342208,
                "command_line": "C:\\Program Files\\nodejs\\node.exe C:\\Users\\WangYunjian\\Desktop\\test\\app.js",
                "process_name": "",
                "process_id": "8564",
                "process_memory_size": 10505040,
                "architecture": "x64",
                "o_s_name": "Windows_NT",
                "o_s_version": "10.0.14393",
                "ip_address": "192.168.20.103",
                "machine_name": "DESKTOP-ABMNEVC",
                "runtime_version": "v4.6.1",
                "data": {
                    "loadavg": [
                        0,
                        0,
                        0
                    ],
                    "platform": "win32",
                    "tmpdir": "C:\\Users\\WANGYU~1\\AppData\\Local\\Temp",
                    "uptime": 8641.2762081,
                    "endianness": "LE"
                }
            }
        },
        "tags": []
    }
]

in dashboard
qq 20161109223050

if i use this function

client.createLog('app.logger', 'createLog then submit', 'Info').submit()

result has change and process_name is unreadable chars

[
    {
        "date": "2016-11-09T14:27:48.224Z",
        "type": "log",
        "source": "app.logger",
        "message": "createLog then submit",
        "data": {
            "@level": "Info",
            "@environment": {
                "processor_count": 4,
                "total_physical_memory": 8485175296,
                "available_physical_memory": 4271304704,
                "command_line": "C:\\Program Files\\nodejs\\node.exe C:\\Users\\WangYunjian\\Desktop\\test\\app.js",
                "process_name": "��(5�\u0001",
                "process_id": "4612",
                "process_memory_size": 10505040,
                "architecture": "x64",
                "o_s_name": "Windows_NT",
                "o_s_version": "10.0.14393",
                "ip_address": "192.168.20.103",
                "machine_name": "DESKTOP-ABMNEVC",
                "runtime_version": "v4.6.1",
                "data": {
                    "loadavg": [
                        0,
                        0,
                        0
                    ],
                    "platform": "win32",
                    "tmpdir": "C:\\Users\\WANGYU~1\\AppData\\Local\\Temp",
                    "uptime": 8709.7455583,
                    "endianness": "LE"
                }
            }
        },
        "tags": []
    }
]

in dashboard

qq 20161109223101

i use windows 10 and language is chinese , file encoding is utf8

Does Exceptionless use proxy settings?

I'm having a problem getting my log and error messages through to the server from my local machine.

I have a simple test script that is sending a sample error message.

I have enabled debugging and I can see it is trying to submit to https://collector.exceptionless.io

However I get an error response like this:

[info] Exceptionless: Enqueuing event: 1488805279857 type=error
[info] Exceptionless: Processing queue...
[info] Exceptionless: Sending 1 events to https://collector.exceptionless.io.
[info] Exceptionless: Updating settings from v0 to vNaN
[info] Exceptionless: Checking for updated settings from: v0.
[error] Exceptionless: Error submitting events: Unauthorized
[info] Exceptionless: Suspending processing for 5 minutes.
[info] Exceptionless: Updating settings timer with delay: undefined
[info] Exceptionless: Finished processing queue.
[error] Exceptionless: Unable to parse settings: '<!DOCTYPE html public "-//W3C//DTD HTM

Where the HTML response is from my employers proxy.

I have tried setting the proxy using environment variables (eg. HTTP_PROXY, https_proxy) and via npm config set ... but it makes no difference.

How can I enable Exceptionless to use a proxy or am I doing something fundamentally wrong? I have a valid API key set and have followed the example pretty accurately.

My test script looks like this:

var exceptionlessClient = require('exceptionless').ExceptionlessClient.default;

exceptionlessClient.config.apiKey = '<API key>';
exceptionlessClient.config.useDebugLogger();

var err = new Error('oh shi');

exceptionlessClient.submitException(err);

Add support for stringifying event data with a maxDepth

I received some HTTP error 413 calls in the console log. After inspection why the event submission failed, I found out it was about the send in over 5MB of stuff while posting as little as 3 events.

In this case it was caused by the angular integration / feature reporting, based on ngRoute.
Path of the biggest chunks of data data are

and also

$template should probably not be included in the events, but I'm not sure if there are others. Best idea might be to pick the properties that should be included, instead of keeping an exclusion list?

Unhandled exceptions in Node.js

Problem

When an unhandled exception occurs, by default, Node.js writes the exception to the console and exits the process.

As I understand the source code and infer from other Exceptionless clients, the exceptionless.node.js client should extend that behavior by submitting the exception before the process quits. It doesn't do that. In fact, manually submitting errors and log messages works as expected, as long as the process keeps running long enough to submit the queue. But as soon as an unhandled exception occurs, it will be ignored:

var client = require("./dist/exceptionless.node.js").ExceptionlessClient.default;

client.config.apiKey = "YOUR_KEY";
client.config.useDebugLogger();

client.submitLog("Test: Log");

throw new Error("Test: Error");

Running this code will neither submit the log message nor the unhandled exception.

Causes

Inspection of exceptionless.node.ts and DefaultEventQueue.ts show several problems:

  1. When exceptionless.node.js is loaded, it subscribes the UNCAUGHT_EXCEPTION and BEFORE_EXIT events on the global process object. The Node documentation states that those events are named in lower camel case (uncaughtException and beforeExit) instead. They have been named like that since the process class has been first introduced in Node.

  2. For some reason, the uncaught-handler doesn't include a call to queue.process while the beforeExit-handler does. But the beforeExit event will never be emitted in case of an unhandled exception:

    'beforeExit' is not emitted for conditions causing explicit termination, such as process.exit() or uncaught exceptions (...)

  3. If the uncaught-handler was registered correctly, in the event of an unhandled exception it would keep the application running, thereby leaving it in an undefined state. This is bad behavior according to the Node docs:

    If a listener is added for this exception, the default action (which is to print a stack trace and exit) will not occur.

    (...)

    An unhandled exception means your application - and by extension Node.js itself - is in an undefined state. Blindly resuming means anything could happen.

    (...)

    uncaughtException should be used to perform synchronous cleanup before shutting down the process. It is not safe to resume normal operation after uncaughtException. If you do use it, restart your application after every unhandled exception!

  4. queue.process is asynchronous, as it submits messages using http requests. Though, it has no means of signaling an empty queue. This would be needed for implementing a submit-exception-then-exit behavior.

Discussion

In my opinion, exceptionless.js should assist the user in adding low-ceremony error logging to their applications while making reasonable choices for common use cases, as other Exceptionless clients already successfully do. Unhandled exceptions are a rather common use case, so what seems to be reasonable, unobtrusive behavior in the event of an unhandled exception?

Without reading any docs or sources, I would have expected requiring("exceptionless") and setting athe api key to enable the following:

  1. An unhandled exception occurs.
  2. The error is logged to the console.
  3. The exception is added to the submission queue.
  4. The submission queue gets processed. No other code is allowed to run in the meantime.
  5. Any errors in regard to submitting the queue also get logged to the console.
  6. The process exits with code 1.

This would be in accordance to the Node documentation by not letting any application code run after an unhandled exception occurs.

Step 4 in particular seems tricky to get right. In an asynchronous environment like Node, how can we process our queue while blocking any other code from execution? There is no http.requestSync.

Some libraries try to imitate synchronous behavior using child_process.spawnSync - this would require forwarding the currently queued messages and configuration as arguments, submitting the queue in the subprocess and returning any errors to the parent process.

Before I go ahead and mess with the codebase, I would appreciate any of your comments about this topic.

Populate extra exception properties

We should be looking at the exception object and storing any extra properties for example for the error object looks like this:

{
    "stack": "xyz",
    "message": "test",
    "extraproperty": "test"
}

We should be storing extraproperty as an object in extended data as shown here: https://github.com/exceptionless/Exceptionless.Net/search?utf8=✓&q=extra We might need to create an exception that has this in c# and look at the json that is created so we ensure the added dictionary is correct for deserialization..

NOTE: There are known exception properties that should be ignored: https://github.com/csnover/TraceKit/blob/master/spec/fixtures/captured-errors.js

Simplify session events and heartbeats

It should be as easy as possible to get started with session start/end and heartbeats. I think we should try to achieve one of these situations

  • All I need to do is call setUserIdentity and useSessions (opt-in for session usage)
  • All I need to do is call setUserIdentity (handle everyting automatically

Right now when useSessions is called, the session only really starts when another event comes in. For users that don't do full feature logging, or submit logging in common cases, this might cause the heartbeat plugin to start its interval later than the actual session start; and might event cause sessions to be missed altogether (when no exceptions occur, and nothing else gets logged).

I'm currently working around this by storing the user identity in sessionStorage. Whenever it changes I call submitSessionStart, whenever it changes from a non-null value to another value, I call submitSessionEnd on the old identity.
I also manually schedule heartbeats.

Sample code / workaround

    function submitHeartbeat() {
        var client = exceptionless.ExceptionlessClient.default;
        var user = client.config.defaultData['@user'];
        if (user && user.identity) {
            var cachedId = sessionStorage.exceptionlessUserId;
            if (cachedId !== user.identity) {
                sessionStorage.exceptionlessUserId = user.identity;

                // TODO: maybe check this also when user.identity is null                
                if (cachedId) {
                    // user changed from one value to another, call end with the old id
                    client.submitSessionEnd(cachedId)
                }
                // user changed. call start to create a new sessions
                client.submitSessionStart();
            } else {
                // user didn't change -> heartbeat
                client.submitSessionHeartbeat(user.identity);
            }
        }
    }
    setInterval(submitHeartbeat, 30000); // heartbeat every 30 seconds
    submitHeartBeat(); // submit the start event right away

Ignore errors created from extensions

TypeError: Cannot read property 'push' of undefined
at Object.logRow() in chrome-extension://bmagokdooijbeehmkpknfglimnifench/firebug-lite.js:line 30905:col 26
at Object.logFormatted() in chrome-extension://bmagokdooijbeehmkpknfglimnifench/firebug-lite.js:line 30894:col 17
at Object.sysout() in chrome-extension://bmagokdooijbeehmkpknfglimnifench/firebug-lite.js:line 30842:col 17
at Object.CssAnalyzer.processAllStyleSheets() in chrome-extension://bmagokdooijbeehmkpknfglimnifench/firebug-lite.js:line 25751:col 17
at Object.initialize() in chrome-extension://bmagokdooijbeehmkpknfglimnifench/firebug-lite.js:line 6289:col 29
at <anonymous>() in chrome-extension://bmagokdooijbeehmkpknfglimnifench/firebug-lite.js:line 9716:col 29
at t() in https://cdn.rawgit.com/exceptionless/Exceptionless.JavaScript/v1.4.3/dist/exceptionless.min.js:line 1:col 260
at t() in https://test/Content/js/Exceptionless/exceptionless.min.js:line 1:col 260

Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience.

Got some more information regarding the origin of that Synchronous XMLHttpRequest. Throughout we could use this as a place to discuss and troubleshoot further.

[Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
loadSource @ exceptionless.js:411
getSource @ exceptionless.js:446
gatherContext @ exceptionless.js:500
computeStackTraceFromStackProp @ exceptionless.js:791
computeStackTrace @ exceptionless.js:1162
traceKitWindowOnError @ exceptionless.js:199
invokeGuardedCallbackDev @ react-dom.development.js:1338
invokeGuardedCallback @ react-dom.development.js:1195
performWork @ react-dom.development.js:12800
scheduleUpdateImpl @ react-dom.development.js:13185
scheduleUpdate @ react-dom.development.js:13124
enqueueSetState @ react-dom.development.js:9646
webpackJsonp../node_modules/react/cjs/react.development.js.ReactComponent.setState @ react.development.js:218
(anonymous) @ async-component.js:25
Promise resolved (async)
render @ async-component.js:23
finishClassComponent @ react-dom.development.js:10249
updateClassComponent @ react-dom.development.js:10226
beginWork @ react-dom.development.js:10605
performUnitOfWork @ react-dom.development.js:12573
workLoop @ react-dom.development.js:12682
callCallback @ react-dom.development.js:1299
invokeGuardedCallbackDev @ react-dom.development.js:1338
invokeGuardedCallback @ react-dom.development.js:1195
performWork @ react-dom.development.js:12800
batchedUpdates @ react-dom.development.js:13244
performFiberBatchedUpdates @ react-dom.development.js:1646
stackBatchedUpdates @ react-dom.development.js:1637
batchedUpdates @ react-dom.development.js:1651
batchedUpdatesWithControlledComponents @ react-dom.development.js:1664
dispatchEvent @ react-dom.development.js:1874

Breadcrumbs

Would it be possible to have breadcrumbs? The concept of breadcrumbs is rather than shipping log messages constantly incase some thing happens. Instead logs messages are buffered and the last X are sent along with the error.

Submission bug with non English characters

There seems to be an encoding issue when submitting events containing foreign characters (throw new Error("爆炸吧!!!");). The last two characters are missing. We need to look into this.

@srijken We ran into this before, do you remember what it was?

System.Text.Encoding.UTF8.GetString(data);
"[{\"date\":\"2016-10-25T15:31:42.034Z\",\"type\":\"error\",\"data\":{\"@error\":{\"type\":\"Error\",\"message\":\"爆炸吧!!!\",\"stack_trace\":[{\"name\":\"login\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\core\\\\user\\\\user.js\",\"line_number\":5,\"column\":11,\"declaring_type\":\"user\",\"data\":{\"is_native\":false}},{\"name\":\"handle [as handle_request]\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\layer.js\",\"line_number\":82,\"column\":5,\"declaring_type\":\"Layer\",\"data\":{\"is_native\":false}},{\"name\":\"next\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\route.js\",\"line_number\":100,\"column\":13,\"declaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":\"dispatch\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\route.js\",\"line_number\":81,\"column\":3,\"declaring_type\":\"Route\",\"data\":{\"is_native\":false}},{\"name\":\"handle [as handle_request]\",\"file_name\":\"c:\\\\C
ode\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\layer.js\",\"line_number\":82,\"column\":5,\"declaring_type\":\"Layer\",\"data\":{\"is_native\":false}},{\"name\":null,\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":234,\"column\":24,\"declaring_type\":null,\"data\":{\"is_native\":false}},{\"name\":\"proto.process_params\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":312,\"column\":12,\"declaring_type\":\"Function\",\"data\":{\"is_native\":false}},{\"name\":null,\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":228,\"column\":12,\"declaring_type\":null,\"data\":{\"is_native\":false}},{\"name\":\"match_layer\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":295,\"column\":3,\"declaring_type\":\"Function\",\"data\":{\"is_native\":false}},{\"name\":\"next\",\"fil
e_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":189,\"column\":10,\"declaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":\"proto.handle\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":165,\"column\":3,\"declaring_type\":\"Function\",\"data\":{\"is_native\":false}},{\"name\":\"router\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":34,\"column\":12,\"declaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":\"handle [as handle_request]\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\layer.js\",\"line_number\":82,\"column\":5,\"declaring_type\":\"Layer\",\"data\":{\"is_native\":false}},{\"name\":\"trim_prefix\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":270,\"column\":13,\"declaring_type\":\"Object\",\"dat
a\":{\"is_native\":false}},{\"name\":null,\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":237,\"column\":9,\"declaring_type\":null,\"data\":{\"is_native\":false}},{\"name\":\"proto.process_params\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":312,\"column\":12,\"declaring_type\":\"Function\",\"data\":{\"is_native\":false}},{\"name\":null,\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":228,\"column\":12,\"declaring_type\":null,\"data\":{\"is_native\":false}},{\"name\":\"match_layer\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":295,\"column\":3,\"declaring_type\":\"Function\",\"data\":{\"is_native\":false}},{\"name\":\"next\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":189,\"column\":10,\"declaring_typ
e\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":null,\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":191,\"column\":16,\"declaring_type\":null,\"data\":{\"is_native\":false}},{\"name\":\"match_layer\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":295,\"column\":3,\"declaring_type\":\"Function\",\"data\":{\"is_native\":false}},{\"name\":\"next\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":189,\"column\":10,\"declaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":null,\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":560,\"column\":15,\"declaring_type\":null,\"data\":{\"is_native\":false}},{\"name\":\"next\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":186,\"column\":14,\"declaring_
type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":null,\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":191,\"column\":16,\"declaring_type\":null,\"data\":{\"is_native\":false}},{\"name\":\"match_layer\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":295,\"column\":3,\"declaring_type\":\"Function\",\"data\":{\"is_native\":false}},{\"name\":\"next\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":189,\"column\":10,\"declaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":\"proto.handle\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":165,\"column\":3,\"declaring_type\":\"Function\",\"data\":{\"is_native\":false}},{\"name\":\"router\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":34,\"c
olumn\":12,\"declaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":\"handle [as handle_request]\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\layer.js\",\"line_number\":82,\"column\":5,\"declaring_type\":\"Layer\",\"data\":{\"is_native\":false}},{\"name\":\"trim_prefix\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":270,\"column\":13,\"declaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":null,\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":237,\"column\":9,\"declaring_type\":null,\"data\":{\"is_native\":false}},{\"name\":\"proto.process_params\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":312,\"column\":12,\"declaring_type\":\"Function\",\"data\":{\"is_native\":false}},{\"name\":null,\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\
router\\\\index.js\",\"line_number\":228,\"column\":12,\"declaring_type\":null,\"data\":{\"is_native\":false}},{\"name\":\"match_layer\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":295,\"column\":3,\"declaring_type\":\"Function\",\"data\":{\"is_native\":false}},{\"name\":\"next\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":189,\"column\":10,\"declaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":\"error\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\serve-static\\\\index.js\",\"line_number\":106,\"column\":7,\"declaring_type\":\"SendStream\",\"data\":{\"is_native\":false}},{\"name\":\"emitOne\",\"file_name\":\"events.js\",\"line_number\":96,\"column\":13,\"declaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":\"emit\",\"file_name\":\"events.js\",\"line_number\":188,\"column\":7,\"declaring_type\":\"SendStream\",\"data\":{\"is_native\":false}}
,{\"name\":\"error\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\send\\\\index.js\",\"line_number\":244,\"column\":17,\"declaring_type\":\"SendStream\",\"data\":{\"is_native\":false}},{\"name\":\"onStatError\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\send\\\\index.js\",\"line_number\":340,\"column\":48,\"declaring_type\":\"SendStream\",\"data\":{\"is_native\":false}},{\"name\":\"next\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\send\\\\index.js\",\"line_number\":591,\"column\":16,\"declaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":\"onstat\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\send\\\\index.js\",\"line_number\":580,\"column\":14,\"declaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":\"oncomplete\",\"file_name\":\"fs.js\",\"line_number\":123,\"column\":15,\"declaring_type\":\"FSReqWrap\",\"data\":{\"is_native\":false}}]},\"@request\":{\"client_ip_address\":\"::1\",\"user_agent\":\"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleW
ebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36\",\"is_secure\":false,\"http_method\":\"GET\",\"host\":\"localhost\",\"path\":\"/login\",\"post_data\":{},\"cookies\":{},\"query_string\":{},\"port\":3000},\"@environment\":{\"processor_count\":4,\"total_physical_memory\":8589447168,\"available_physical_memory\":2402754560,\"command_line\":\"C:\\\\Program Files\\\\nodejs\\\\node.exe c:\\\\Code\\\\Demo\\\\bin\\\\www start\",\"process_name\":\"C:\\\\Program Files\\\\nodejs\\\\node.exe\",\"process_id\":\"12228\",\"process_memory_size\":21008384,\"architecture\":\"x64\",\"o_s_name\":\"Windows_NT\",\"o_s_version\":\"10.0.14393\",\"ip_address\":\"10.211.55.7\",\"machine_name\":\"dev-vm\",\"runtime_version\":\"v6.9.1\",\"data\":{\"loadavg\":[0,0,0],\"platform\":\"win32\",\"tmpdir\":\"C:\\\\Users\\\\blake\\\\AppData\\\\Local\\\\Temp\",\"uptime\":1022016.9880571,\"endianness\":\"LE\"}},\"@submission_method\":\"express\"}"

Default encoding ("Western European (Windows)")

System.Text.Encoding.Default.GetString(data);
"[{\"date\":\"2016-10-25T15:31:42.034Z\",\"type\":\"error\",\"data\":{\"@error\":{\"type\":\"Error\",\"message\":\"爆炸å\u0090§ï¼\u0081ï¼\u0081ï¼\u0081\",\"stack_trace\":[{\"name\":\"login\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\core\\\\user\\\\user.js\",\"line_number\":5,\"column\":11,\"declaring_type\":\"user\",\"data\":{\"is_native\":false}},{\"name\":\"handle [as handle_request]\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\layer.js\",\"line_number\":82,\"column\":5,\"declaring_type\":\"Layer\",\"data\":{\"is_native\":false}},{\"name\":\"next\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\route.js\",\"line_number\":100,\"column\":13,\"declaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":\"dispatch\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\route.js\",\"line_number\":81,\"column\":3,\"declaring_type\":\"Route\",\"data\":{\"is_native\":false}},{\"name\":\"handle [as handle_re
quest]\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\layer.js\",\"line_number\":82,\"column\":5,\"declaring_type\":\"Layer\",\"data\":{\"is_native\":false}},{\"name\":null,\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":234,\"column\":24,\"declaring_type\":null,\"data\":{\"is_native\":false}},{\"name\":\"proto.process_params\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":312,\"column\":12,\"declaring_type\":\"Function\",\"data\":{\"is_native\":false}},{\"name\":null,\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":228,\"column\":12,\"declaring_type\":null,\"data\":{\"is_native\":false}},{\"name\":\"match_layer\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":295,\"column\":3,\"declaring_type\":\"Function\",\"data\":{\"is_native\":
false}},{\"name\":\"next\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":189,\"column\":10,\"declaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":\"proto.handle\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":165,\"column\":3,\"declaring_type\":\"Function\",\"data\":{\"is_native\":false}},{\"name\":\"router\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":34,\"column\":12,\"declaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":\"handle [as handle_request]\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\layer.js\",\"line_number\":82,\"column\":5,\"declaring_type\":\"Layer\",\"data\":{\"is_native\":false}},{\"name\":\"trim_prefix\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":270,\"column\":13,\"d
eclaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":null,\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":237,\"column\":9,\"declaring_type\":null,\"data\":{\"is_native\":false}},{\"name\":\"proto.process_params\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":312,\"column\":12,\"declaring_type\":\"Function\",\"data\":{\"is_native\":false}},{\"name\":null,\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":228,\"column\":12,\"declaring_type\":null,\"data\":{\"is_native\":false}},{\"name\":\"match_layer\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":295,\"column\":3,\"declaring_type\":\"Function\",\"data\":{\"is_native\":false}},{\"name\":\"next\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":1
89,\"column\":10,\"declaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":null,\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":191,\"column\":16,\"declaring_type\":null,\"data\":{\"is_native\":false}},{\"name\":\"match_layer\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":295,\"column\":3,\"declaring_type\":\"Function\",\"data\":{\"is_native\":false}},{\"name\":\"next\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":189,\"column\":10,\"declaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":null,\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":560,\"column\":15,\"declaring_type\":null,\"data\":{\"is_native\":false}},{\"name\":\"next\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\
":186,\"column\":14,\"declaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":null,\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":191,\"column\":16,\"declaring_type\":null,\"data\":{\"is_native\":false}},{\"name\":\"match_layer\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":295,\"column\":3,\"declaring_type\":\"Function\",\"data\":{\"is_native\":false}},{\"name\":\"next\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":189,\"column\":10,\"declaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":\"proto.handle\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":165,\"column\":3,\"declaring_type\":\"Function\",\"data\":{\"is_native\":false}},{\"name\":\"router\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\i
ndex.js\",\"line_number\":34,\"column\":12,\"declaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":\"handle [as handle_request]\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\layer.js\",\"line_number\":82,\"column\":5,\"declaring_type\":\"Layer\",\"data\":{\"is_native\":false}},{\"name\":\"trim_prefix\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":270,\"column\":13,\"declaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":null,\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":237,\"column\":9,\"declaring_type\":null,\"data\":{\"is_native\":false}},{\"name\":\"proto.process_params\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":312,\"column\":12,\"declaring_type\":\"Function\",\"data\":{\"is_native\":false}},{\"name\":null,\"file_name\":\"c:\\\\Code\\\\Demo\\\\no
de_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":228,\"column\":12,\"declaring_type\":null,\"data\":{\"is_native\":false}},{\"name\":\"match_layer\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":295,\"column\":3,\"declaring_type\":\"Function\",\"data\":{\"is_native\":false}},{\"name\":\"next\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\express\\\\lib\\\\router\\\\index.js\",\"line_number\":189,\"column\":10,\"declaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":\"error\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\serve-static\\\\index.js\",\"line_number\":106,\"column\":7,\"declaring_type\":\"SendStream\",\"data\":{\"is_native\":false}},{\"name\":\"emitOne\",\"file_name\":\"events.js\",\"line_number\":96,\"column\":13,\"declaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":\"emit\",\"file_name\":\"events.js\",\"line_number\":188,\"column\":7,\"declaring_type\":\"SendStream\"
,\"data\":{\"is_native\":false}},{\"name\":\"error\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\send\\\\index.js\",\"line_number\":244,\"column\":17,\"declaring_type\":\"SendStream\",\"data\":{\"is_native\":false}},{\"name\":\"onStatError\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\send\\\\index.js\",\"line_number\":340,\"column\":48,\"declaring_type\":\"SendStream\",\"data\":{\"is_native\":false}},{\"name\":\"next\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\send\\\\index.js\",\"line_number\":591,\"column\":16,\"declaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":\"onstat\",\"file_name\":\"c:\\\\Code\\\\Demo\\\\node_modules\\\\send\\\\index.js\",\"line_number\":580,\"column\":14,\"declaring_type\":\"Object\",\"data\":{\"is_native\":false}},{\"name\":\"oncomplete\",\"file_name\":\"fs.js\",\"line_number\":123,\"column\":15,\"declaring_type\":\"FSReqWrap\",\"data\":{\"is_native\":false}}]},\"@request\":{\"client_ip_address\":\"::1\",\"user_agent\":\"Mozilla/5.0
 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36\",\"is_secure\":false,\"http_method\":\"GET\",\"host\":\"localhost\",\"path\":\"/login\",\"post_data\":{},\"cookies\":{},\"query_string\":{},\"port\":3000},\"@environment\":{\"processor_count\":4,\"total_physical_memory\":8589447168,\"available_physical_memory\":2402754560,\"command_line\":\"C:\\\\Program Files\\\\nodejs\\\\node.exe c:\\\\Code\\\\Demo\\\\bin\\\\www start\",\"process_name\":\"C:\\\\Program Files\\\\nodejs\\\\node.exe\",\"process_id\":\"12228\",\"process_memory_size\":21008384,\"architecture\":\"x64\",\"o_s_name\":\"Windows_NT\",\"o_s_version\":\"10.0.14393\",\"ip_address\":\"10.211.55.7\",\"machine_name\":\"dev-vm\",\"runtime_version\":\"v6.9.1\",\"data\":{\"loadavg\":[0,0,0],\"platform\":\"win32\",\"tmpdir\":\"C:\\\\Users\\\\blake\\\\AppData\\\\Local\\\\Temp\",\"uptime\":1022016.9880571,\"endianness\":\"LE\"}},\"@submission_method\":\"express\"}"

QueueTimer keeps Node process from terminating gracefully

var client = require('exceptionless').ExceptionlessClient.default;
client.config.apiKey = "***";
client.config.useDebugLogger();

This program will run and exit as expected. No events are submitted. Console output:

[info] Exceptionless: Processing queue...
franks-macbook:Exceptionless.JavaScript Frank$ 

Whereas, if we modify the code to submit an event:

var client = require('exceptionless').ExceptionlessClient.default;
client.config.apiKey = "***";
client.config.useDebugLogger();
client.submitLog('Test');

This program will run forever, unless you terminate it by sending SIGINT:

[info] Exceptionless: Enqueuing event: 1456470547394 type=log 
[info] Exceptionless: Processing queue...
[info] Exceptionless: Sending 1 events to https://collector.exceptionless.io.
[info] Exceptionless: Sent 1 events.
[info] Exceptionless: Finished processing queue.
[info] Exceptionless: Processing queue...
[info] Exceptionless: Processing queue...
[info] Exceptionless: Processing queue...

If we npm install wtfnode and call .dump(), it clearly shows what's going on:

[WTF Node?] open handles:
- Sockets:
  - undefined:undefined -> undefined:undefined
    - Listeners:
  - undefined:undefined -> undefined:undefined
    - Listeners:
- Timers:
  - (10000 ~ 10 s) wrapper @ /Users/Frank/Entw..../exceptionless.node.js:242

From Node docs:

In Node there is no such start-the-event-loop call. Node simply enters the event loop after executing the input script. Node exits the event loop when there are no more callbacks to perform.

So, our timer is the last single callback in Node's event loop and therefore blocks it from exiting. This is probably not an issue for service-like applications, but it sucks for console tools or anything that should just exit when the work is finished.

Thoughts:

  • Can we use a shorter timespan for the timer in combination with a lastEventTimestamp field?
  • Can we leverage the same private API that wtfnode uses to figure out if we are the single reason that the process is still running?
  • How long do we want to wait for events to be submitted if the program has no work to do otherwise, before exiting? Should it wait forever if events cannot be submitted due to network problems? Should it make a difference between InMemory and LocalStorage?

Queue timer fires even when api key isn't configured

I setup Exceptionless.UI to not set the api key by default but events are still enqueued (I don't want them sent and rejected). However, I started seeing this in the console.

[info] Exceptionless: Enqueuing event: 1460562831592 type=usage  exceptionless.js:1285:13
[info] Exceptionless: user identity: [email protected] exceptionless.js:1285:13
[info] Exceptionless: Processing queue... exceptionless.js:1285:13
[info] Exceptionless: Invalid Api Key. The queue will not be processed. exceptionless.js:1285:13
[info] Exceptionless: Processing queue... exceptionless.js:1285:13
[info] Exceptionless: Invalid Api Key. The queue will not be processed. exceptionless.js:1285:13

It appears that we are triggering a timer to run even when configuration is invalid.

Update docs to showcase session tracking and es6 syntax

We need to update the samples to show how to use the client in es6 (import syntax) and add a angular4 sample :). The closest sample we have is our typescript sample: https://github.com/exceptionless/Exceptionless.JavaScript/blob/master/example/TypeScript/index.ts

Here is the old way that needs to be converted to es6 import

         var config = exceptionless.ExceptionlessClient.default.config;
         client.config.useLocalStorage();
         client.config.setVersion(‘1.2.3);
         client.config.setUserIdentity(‘id’, ‘friendlyname’);
         client.config.useSessions();
         client.createFeatureUsage(location.pathname || /).addTags(‘UI’).submit();

Submission method 'jQuery.ajaxError' title is blank

When an exception is handled via jQuery.ajaxError, the title in the Exceptionless UI is blank.

jQuery.ajaxError passes the error string as the 4th argument, which is being passed to processUnhandledException which accepts Error objects. The result is that the error (e.g. "Internal Server Error") is not parsed correctly by TraceKit.

Outputs JSON data as a result:

[{"date":"2015-09-23T21:25:05.685Z","type":"error","source":"api/Some/ApiCall?id=10","data":{"status":500,"response":"{\"Message\":\"An error has occurred.\"}","@error":{"stack_trace":[]},"@request":{"user_agent":"Mozilla/5.0 (Windows NT 6.3; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0","is_secure":true,"host":"www.example.com","port":80,"path":"/","cookies":{"Cookie":""},"query_string":null,"referrer":"https://www.example.com"},"@submission_method":"JQuery.ajaxError"},"tags":["Example","JavaScript"]}]

angular integration fails with angular router

TypeError: Cannot read property 'name' of undefined
at at () in https://localhost/scripts/exceptionless/integrations/angular.js:line 47:col 60
at Scope.$get.Scope.$broadcast() in https://localhost/scripts/angular.js:line 14720:col 28
at at () in https://localhost/scripts/angular-route.js:line 616:col 26
at processQueue() in https://localhost/scripts/angular.js:line 13189:col 27
at at () in https://localhost/scripts/angular.js:line 13205:col 27
at Scope.$get.Scope.$eval() in https://localhost/scripts/angular.js:line 14401:col 28
at Scope.$get.Scope.$digest() in https://localhost/scripts/angular.js:line 14217:col 31
at Scope.$get.Scope.$apply() in https://localhost/scripts/angular.js:line 14506:col 24
at done() in https://localhost/scripts/angular.js:line 9659:col 47
at completeRequest() in https://localhost/scripts/angular.js:line 9849:col 7
at XMLHttpRequest.requestLoaded() in https://localhost/scripts/angular.js:line 9790:col 9

Navigating away from the page loses exceptions if the processing queue has not fired

Using the JavaScript client if an Exception is submitted it isn't sent immediately to Exceptionless, instead it waits for the next 'Processing queue...' event to fire.

While testing this we have observed that if the user navigates away from the current page before the 'Processing queue...' event fires than the exceptions are never logged to Exceptionless. As the 'Processing queue...' event currently fires every 10 seconds it is quite likely that a user would navigate away from a page after an error has occurred. Is there a setting or way to force exceptions to be logged instantly?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.