Skip to content

Instantly share code, notes, and snippets.

@maxmilton
Last active April 27, 2020 15:43
Show Gist options
  • Save maxmilton/e2338b02b7381fc7bef2ccd96f434201 to your computer and use it in GitHub Desktop.
Save maxmilton/e2338b02b7381fc7bef2ccd96f434201 to your computer and use it in GitHub Desktop.
How to load the Sentry JavaScript error tracking script 'raven.js' asynchronously and still capture errors before the script is loaded.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Asynchronous Sentry JavaScript Error Tracking</title>
<!-- putting your CSS near the top is always a good idea -->
<link rel="stylesheet" href="/app.css"></link>
<!--
load raven.js asynchronously
NOTE: crossorigin is recommended on any external scripts so you can capture
errors they throw correctly and to prevent sending credentials when fetching.
-->
<script async src="https://cdn.ravenjs.com/3.22.0/raven.min.js" crossorigin id="raven"></script>
<!--
resolve sentry.io DNS and do TLS+TCP handshakes so the first request is faster
NOTE: If you're using the self-hosted version of Sentry then replace this URL
with your sentry endpoint.
-->
<link rel="preconnect" href="https://sentry.io">
</head>
<body>
<div id="app"></div>
<!-- Javascript error tracking with Sentry -->
<script>
/* global Raven *//* eslint-disable func-names, strict, no-param-reassign, no-multi-assign, prefer-arrow-callback */
(function (window, queue, loaded, script) {
'use strict';
/**
* Optionally expose the loaded state and error queue globally to push
* errors from your app.
*/
// window.sentry.loaded = loaded;
// window.sentry.queue = queue;
// capture and store any errors before raven.js is loaded
window.onerror = function e(message, file, lineNo, columnNo, error) {
if (loaded) return;
queue.push([message, file, lineNo, columnNo, error]);
};
/**
* raven.js doesn't capture unhandled Promise rejections by default due
* to limited compatibility; only Chrome 49+ and some promise libraries
* (e.g. core-js, bluebird) are known to trigger this event.
*/
window.onunhandledrejection = function e(error) {
if (loaded) return;
queue.push([
error.reason.reason || error.reason.message,
error.type,
JSON.stringify(error.reason),
]);
};
/**
* Optionally also track handled Promise rejections (useful for development
* or testing environments). Replace the above onunhandledrejection with:
*/
// window.onunhandledrejection = window.onunhandledrejection =
// function e(error) {
// if (loaded) return;
// queue.push([
// error.reason.reason || error.reason.message,
// error.type,
// JSON.stringify(error.reason),
// ]);
// };
// once raven.js is loaded then install
script.onreadystatechange = script.onload = function () {
if (loaded) return;
loaded = true;
Raven.config('___PUBLIC_DSN___', {
environment: '<%= process.env.NODE_ENV %>', // if the page is a lodash template then the value is injected
release: '<%= process.env.APP_RELEASE %>', // same as above, these are just an example
tags: { app: 'example' },
}).install();
// same compatibility caveats as the above Promise error events
window.onunhandledrejection = function e(error) {
Raven.captureException(new Error(error.reason.reason || error.reason.message), {
extra: {
type: error.type,
reason: JSON.stringify(error.reason),
},
});
};
/** Alternatively also track handled Promise rejections: */
// window.onrejectionhandled = window.onunhandledrejection =
// function e(error) {
// Raven.captureException(new Error(error.reason.reason || error.reason.message), {
// extra: {
// type: error.type,
// reason: JSON.stringify(error.reason),
// },
// });
// };
// report any previously stored errors
queue.forEach(function (error) {
/**
* error[0] = message
* error[1] = file, url, or type
* error[2] = line number or event
* error[3] = column number (old browsers may not emit this)
* error[4] = Error Object (old browsers may not emit this either!)
*/
Raven.captureException(error[4] || new Error(error[0]), {
extra: {
file: error[1],
line: error[2],
col: error[3],
},
});
});
};
}(window, [], false, document.getElementById('raven')));
</script>
<!-- your JavaScript should come after the above code so we can its track errors -->
<script src="/vendor.js"></script>
<script src="/app.js"></script>
</body>
</html>
@imposibrus
Copy link

Correct me if I am wrong, but for recents versions of SDK you can use it like this:

<script src="https://browser.sentry-cdn.com/5.6.1/bundle.min.js" integrity="sha384-pGTFmbQfua2KiaV2+ZLlfowPdd5VMT2xU4zCBcuJr7TVQozMO+I1FmPuVHY3u8KB" crossorigin="anonymous" async id="sentry-sdk"></script>
<script>
    document.getElementById('sentry-sdk').addEventListener('load', function () {
        Sentry.init({ dsn: 'https://<key>@sentry.io/<project>' });
    }, false);
</script>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment