You can get a similar effect of services like Sentry by catching global unhandled errors events and sending them to the back-end to implement a custom error reporting system, eg:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
window.onerror = function (msg, url, lineNo, columnNo, error) {
    let message = {
        'message': msg,
        'url':     url,
        'line':    lineNo,
        'column':  columnNo,
        'stack':   error.stack,

    }
    fetch('/api/report-errors', { method: 'post' , body: JSON.stringify(message)});

    // By returning false we make sure the default error handler processes 
    // the error after we're done with it.
    return false;
}

if('onunhandledrejection' in window){
    window.onunhandledrejection = function(e) {
        let message = {
            'message': e.reason.message,
            'stack':   e.reason.stack,
            'error_type': e.type
        }
        fetch('/api/report-errors', { method: 'post' , body: JSON.stringify(message)});
    }
}

window.onerror includes events like javascript runtime errors, resource loading failures and more. It also has full browser compatibility.

window.onunhandledrejection will handle events raised for unhandled Promise rejections. Before setting the event handler we need to check if it’s supported by the browser.

These handlers can be expanded to included further context and other events can be used as well to build a more comprehensive reporting system.