GithubHelp home page GithubHelp logo

tracekit's Introduction

TraceKit - Cross browser stack traces.

Build

Supports all major browsers, from IE6 to Opera, the Android webview and everywhere in between.

Not all browsers support stack traces on error objects, but TraceKit squeezes out as much useful information as possible and normalizes it. 3kB minified + gzipped

Install

bower install tracekit

This places TraceKit at components/tracekit/tracekit.js. Install bower: npm install bower -g, download npm with Node: http://nodejs.org

Then include the <script> to your page

Usage

First, register a subscriber for error reports:

TraceKit.report.subscribe(function yourLogger(errorReport) {
  //send via ajax to server, or use console.error in development
  //to get you started see: https://gist.github.com/4491219
});

Then, make sure all your code is in a try/catch block:

try {
  /*
   * your application code here
   *
   */
  throw new Error('oops');
} catch (e) {
  TraceKit.report(e); //error with stack trace gets normalized and sent to subscriber
}

In order to get stack traces, you need to wrap your code in a try/catch block like above. Otherwise the error hits window.onerror handler and will only contain the error message, line number, and column number.

You also need to throw errors with throw new Error('foo') instead of throw 'foo'.

You can unsubscribe some subscriber function by doing TraceKit.report.unsubscribe(someFunction)

Eliminating (anonymous function)'s

Api.foo = function Api_foo() {
};
var bar = function barFn() { //'Fn' is to avoid errors in IE
};

We recommend the above convention of function naming, Api_foo always corresponds to Api.foo, barFn corresponds to bar - just as long as the function name is not the same as the identifier. Otherwise, you can have bugs in IE.

Options

TraceKit will attempt to fetch and analyze source files, but you can turn this off using:

TraceKit.remoteFetching = false;

You can also tell TraceKit to ignore global window errors with:

TraceKit.collectWindowErrors = false;

View the source for more details and examples.

Stacktrace or GTFO

Contributing

All code must pass JSHint and tests. Run grunt to compile and run JSHint and grunt test for the test suite. New features need accompanying documentation in the README, changes to existing api's need updated documentation. In general, open an issue for whatever it is you're thinking, get some quick feedback, make good stuff, and we'll accept the PR.

Before building (minifying) you will need to get the closure compiler jar:

wget http://dl.google.com/closure-compiler/compiler-latest.zip
unzip compiler-latest.zip -d closure

License

(The MIT License)

Copyright (c) 2013 Onur Can Cakmak [email protected] and all TraceKit contributors.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

tracekit's People

Contributors

airportyh avatar coxm avatar csnover avatar davidomid avatar dependabot[bot] avatar devinrhode2 avatar frankebersoll avatar frankenlist avatar futpib avatar ghostd avatar hongrich avatar jaredly avatar jasonslyvia avatar johnw424 avatar jrencz avatar justin-steele-idexx avatar kitsunde avatar kornelski avatar mattrobenolt avatar michelebertoli avatar nemo157 avatar niemyjski avatar nimish avatar occ avatar panaggio avatar paulirish avatar pieter avatar theit8514 avatar tobiasbales avatar webysther 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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tracekit's Issues

error.name missing regularly, contained in message

I observed that while error.name is empty regularly, some browsers prepend it to the message.

E.g. when having

throw new DOMException("INDEX_SIZE_ERR");

Those are the observed values:

Opera 12.12
Name: null
Message: Uncaught exception: Error: DOMException: INDEX_SIZE_ERR

Android Browser 4.2 + 4.4
Name: null
Message: Uncaught DOMException: INDEX_SIZE_ERR

Edge 12 + 13
Name: null
Message: DOMException: INDEX_SIZE_ERR

Or when having this:

throw new Error('Foo')

I saw this in the logs:

Safari 9
Name: null
Message: Error: Foo

I also observed native errors like this:

Safari 9
Name: null
Message: TypeError: foo.bar is not a function

Is there any interest in normalizing this stuff in TraceKit? I think we could parse the names out of the message quite easily using some RegEx magic.

I could implement this if it is something you would include in TraceKit.

Firefox trace isn't parsed correctly

Firefox 43 has stack strings like these:

Module.fooFunc/<@https://example.com/foo.js:531:5
Module.fooFunc@https://example.com/foo.js:530:5
Module.barFunc/<@https://example.com/foo.js:40:6
aspect/</dispatcher@https://example.com/vendor/dojotoolkit/dojo/aspect.js:98:25
Module.bazFunc/liNode.onclick@https://example.com/foo.js:444:10

The < seems to indicate anonymous functions, but I have no idea where exactly the dispatcher thing comes from. You can maybe look into Dojo's aspect.js to understand Firefox' behavior here.

Also I'm not sure whether the Function()/eval() stuff documented at MDN (Firefox 30+) is supported, as the pattern doesn't look like it does. Example from MDN:

@file:///C:/example.html line 7 > eval line 1 > eval:1:1
@file:///C:/example.html line 7 > eval:1:1
@file:///C:/example.html:7:6

API documentation should be published

There's JSDoc in the source code, but as far as I can tell it's not rendered and published anywhere. We should publish it - perhaps a gh-pages branch off this repo would be a good place.

Breaks jQuery UI

The jQuery.event.add override causes jQuery UI draggables to never stop dragging.

Angular exception issue

Angular gives exception with stack string as

"ReferenceError: $firebase is not defined
    at new <anonymous> (http://localhost:3474/scripts/controllers/headers/show-controller.js:3:20)
    at d (http://localhost:3474/scripts/vendor/angular.min.js:30:452)
    at Object.instantiate (http://localhost:3474/scripts/vendor/angular.min.js:31:80)
    at $get (http://localhost:3474/scripts/vendor/angular.min.js:62:33)
    at link (http://localhost:3474/scripts/vendor/angular-route.min.js:7:208)
    at H (http://localhost:3474/scripts/vendor/angular.min.js:49:375)
    at f (http://localhost:3474/scripts/vendor/angular.min.js:42:399)
    at http://localhost:3474/scripts/vendor/angular.min.js:42:67
    at $get.m (http://localhost:3474/scripts/vendor/angular.min.js:43:303)
    at A (http://localhost:3474/scripts/vendor/angular.min.js:47:46)"

When i compute stacktrace using TraceKit.computeStackTrace(exception), the result stack array does not include first line

    at new <anonymous> (http://localhost:3474/scripts/controllers/headers/show-controller.js:3:20)

I could see the first line has two word for function name. Will that be problem?

Catch unhandled promise rejection events

Promise rejection events can be caught via the window.onunhandledrejection event. If an exception is thrown during processing of a Promise (either during its initial execution phase or during processing a "then" function attached to it), the Promise is rejected and the "reason" entry in the rejection event will be an Error. reason may also be any other type, as it will be populated with whatever argument is given in calls to the reject function of the Promise handler, so will need to be checked before handling. I'm not sure how TraceKit should behave if it catches an unhandled rejection that is not an Error.

Support for this feature of Promises isn't great yet, but is improving (see http://caniuse.com/#feat=unhandledrejection).

New release?

Any chance of putting up a new release on NPM? Thanks!

toString for error stack

Right now as far as I can tell the stack is a very informative javascript object whereas in native exceptions - it is a string.

I think it will be a good idea to add some presets for toStringing stack, so it is easier to look at and display etc.

If you think it is a good idea too I can try to comeup with some solution.

setTimeout, setInterval wrappers return undefined instead of the handle

Too lazy to do a pull request; here's a patch:

--- tracekit.js 2011-01-02 16:54:15.000000000 -0800
+++ tk2.js      2011-01-03 17:59:31.699916000 -0800
@@ -971,7 +971,7 @@
                          }
                };

-               _oldSetTimeout.apply(this, arguments);
+               return _oldSetTimeout.apply(this, arguments);
        };

        // If you are reading this, you should know that setInterval is
@@ -991,7 +991,7 @@
                        }
                };

-               _oldSetInterval.apply(this, arguments);
+               return _oldSetInterval.apply(this, arguments);
        };
 }(window));

Module loading code throws errors in strict mode

In the check if (typeof module !== 'undefined' && module.exports && this.module !== module) the this.module part fails in strict mode, where this is undefined. Since this check is intended to determine if the module in scope is coming from the global scope, replacing with window.module gives the correct behavior.

Support blob: URLs

createObjectURL() can be used to create a URL in format blob:http://origin/uuid that's very handy for creating Web Workers and we also create <script> elements with these Blob URLs as part of workarounds for appcache being appcache.

The problem is that TraceKit doesn't recognize blob: URLs, and therefore Sentry doesn't recognize them either, so we don't get backtraces in our error reports.

Could you add support for blob: URLs?

If needed, our app would be able to provide mapping from blob: URLs to equivalent HTTP file URLs or return its content as a string.

Handle frames generated by Firefox internal errors (e.g. NS_ERROR_FAILURE)

It's possible to get Firefox to generate errors that bubble up from its internals. They can generate bizarre stack trace formats that are not currently handled by TraceKit.

More here: https://developer.mozilla.org/en-US/docs/Mozilla/Errors

Example error.stack from such an error, generated by try/catch around w/ XMLHttpRequest.prototype.send that fails in a specific situation:

[2]</Raven.prototype._wrapBuiltIns/</<@http://127.0.0.1:8002/dist/raven.js:703:28
App.prototype.foo@file:///Users/benvinegar/Projects/sentry/index.html:15:2
bar@file:///Users/benvinegar/Projects/sentry/index.html:20:3
@file:///Users/benvinegar/Projects/sentry/index.html:23:1

TraceKit parses the first frame into:

{
  url: "[2]</Raven.prototype._wrapBuiltIns/</<@http://127.0.0.1:8002/dist/raven.js",
  func: "?",
  args: [],
  line: 703,
  column: 28
}

More info on how I generated this error in getsentry/sentry-javascript#528

Add support for plugins

We should try and modularize the code base so the jquery/ajax and window.onerror logic is separated out. So if you're not using it, you're not paying the overhead cost.

Unable to set remoteFetching in TypeScript

The way remoteFetching is defined and exported makes it (nearly?) impossible to modify in a TypeScript context.

This example causes a TS error:

import * as TraceKit from 'tracekit';

TraceKit.remoteFetching = false;

And the error:

semantic error TS2540 Cannot assign to 'remoteFetching' because it is a constant or a read-only property.

I've tried to trick typescript into allowing modification of this by assigning it to another variable but its properties have had Object.preventExtensions marked on them, which I'm guessing is part of the module import contract.

Thanks for a great library!

Fix flakey tests

There are five flakey tests that have to do with ensuring the window.onerror is called and works properly. This needs to be mocked or figure out why the test occasionally hangs.

      - should pass undefined:undefined...
log: window.onerror(undefined, undefined, 1337, undefined)

log: matches test message and line number
       X should pass undefined:undefined
         Error: Timeout - Async function did not complete within 5000ms (set by jasmine.DEFAULT_TIMEOUT_INTERVAL) (1)
>> Error: Timeout - Async function did not complete within 5000ms (set by jasmine.DEFAULT_TIMEOUT_INTERVAL) Error: Timeout - Async function did not complete within 5000ms (set by jasmine.DEFAULT_TIMEOUT_INTERVAL)
>>     at <Jasmine>
     when no 5th argument (error object)

Update docs for TypeScript

There really should be some information on how to use this lib through npm and TypeScript.

I'm trying to get this to work in an Angular 2 based project with not much luck.

NuGet package

First let me say that i really enjoy using your library and thank you for the hard work.

Can you create a nuget package for this library?

Thanks.

TraceKit Report is not exported from package

import * as TraceKit  from 'tracekit';

TraceKit.report.subscribe(tracekitErrorHandler)

I added tracekit in my ts file. I try to run that file, I got error like below

report is not exported by ../../node_modules/tracekit/tracekit.js
80:                 });
81:             };
82:             TraceKit.report.subscribe(tracekitErrorHandler);

Unexpected error when computing Gecko stack traces

By reviewing TraceKit code, I found an issue where the stack trace computation fails in certain condition. Keep in mind that I didn't observe an actual error matching this condition.

See the code in question:

                } else if (i === 0 && !parts[5] && !_isUndefined(ex.columnNumber)) {
                    // ...
                    stack[0].column = ex.columnNumber + 1;
                }

The issue is, if i === 0, then the stack array is always empty, so accessing its first element returns undefined, and stack[0].column throws TypeError: Cannot set properties of undefined.

This piece of code is only used in Gecko if the first line doesn't contain any column number. You can see the tests failing if you remove the column number here for example.

Now, because this has been an issue for a long time and nobody reported it, I'm not sure if this should be fixed or if this particular condition could be removed altogether. It seems that Sentry chose the latter.

Cannot read property 'name' of undefined

I've got an error like in title. It's in function computeStackTrace in last return when tries to get ex.name.

It is called by function traceKitWindowOnUnhandledRejection (and I don't have more stacktrace).

Could you tell me why I got this error?

jQuery detection detectng more than jQuery

The jQuery detection here:
if (!$) {
return;
}

detects any $ function as jQuery, which is often not the case. When another $ function exists it passes this test and i then get various other errors below this line.

a good alternative seems to be
if (typeof jQuery == 'undefined') {
return;
}

hope you can include this is the next update

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

I get the following error in chrome when loadSource is called:

Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/.
function loadSource(url) {
        if (typeof url !== 'string') {
          return [];
        }

        if (!TraceKit.remoteFetching) { //Only attempt request if remoteFetching is on.
            return '';
        }
        try {
            var getXHR = function() {
                try {
                    return new window.XMLHttpRequest();
                } catch (e) {
                    // explicitly bubble up the exception if not found
                    return new window.ActiveXObject('Microsoft.XMLHTTP');
                }
            };

            var request = getXHR();
            request.open('GET', url, false);
            request.send('');
            return request.responseText;
        } catch (e) {
            return '';
        }
    }

ESLint problems for tracekit.js

Hi, on running ES linter with browser configurations for tracekit.js file found a few issues , can we may be configure a linter in git actions to fix these issues automatically ?
Screenshot 2021-11-28 at 10 30 49 PM

Object doesn't support property or method at return _oldSetTimeout.apply(this, arguments)

i'm getting quite a few errors like this.

Object doesn't support this property or method
at line
return _oldSetTimeout.apply(this, arguments);

I dont use setTimeout on my site. It seems some services are injecting JS onto my web pages as immediatley before this error i get another error. For example:
Object doesn't support this property or method
at
https://www.superfish.com/ws/sf_conduit.jsp line 484
which is:
setTimeout( (function(u){return function(){cBack( u )}})(prm), 300 );
i can send the enitre JS file if needed.

I wonder if this JS might be using setTimeout in a way your code doesn't expect? Thats my best guess at the moment.

immediatley before this i also get an error like this:
Could not load 'dojo.io.script'; last tried 'https://ajax.googleapis.com/ajax/libs/dojo/1.5.0/dojo/io/script.js'
in
https://ajax.googleapis.com/ajax/libs/dojo/1.5.0/dojo/dojo.xd.js
but i'd guess this is unrelated, mabe even somethign dojo is supposed to do.

These all come from the same IP, all at the same time (down to the second), with a user agent that seems to be IE8:
Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; YPC 3.2.0; GTB6.6; .NET CLR 1.1.4322; InfoPath.2; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; Seekmo 10.3.79.0; yie8)

I could remove your W function, but as injecting JS code seems to be really quite common i'd rather keep W so i know when code injection causes problems with my site.

Any ideas what superfish.com's setTimeout could be causing problems?

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.