Skip to content

JavaScript errors

JavaScript error tracking captures client-side errors and reports them through your own application. When enabled, the package registers a POST route at /ranetrace/javascript-errors/store (named ranetrace.javascript-errors.store, throttled to 60 requests per minute) and exposes a Blade directive that renders the client-side script.

Add the Blade directive

Place @ranetraceErrorTracking in your layout (commonly before </body>). This is code, so it deploys with your app:

<!DOCTYPE html>
<html>
<body>
    @yield('content')

    @ranetraceErrorTracking
</body>
</html>

The directive renders the ranetrace::error-tracker view. When javascript_errors.enabled is false, the directive renders nothing, so it is safe to leave in place even before the feature is on.

Turn it on in production

JavaScript error tracking runs where your users are, so enable it in your production environment, not just a local .env:

RANETRACE_ENABLED=true
RANETRACE_JAVASCRIPT_ERRORS_ENABLED=true

To try it during development, set the same flags in your local .env.

What the script captures

From resources/views/error-tracker.blade.php:

  • window.onerror: uncaught exceptions.
  • unhandledrejection: unhandled promise rejections.
  • Console errors: only when RANETRACE_JAVASCRIPT_ERRORS_CAPTURE_CONSOLE_ERRORS=true (default: false).

It also collects breadcrumbs leading up to the error:

Category Tracked events
navigation Page loaded
user Clicks (tag, id, class, first 50 chars of text), form submissions (action, method)
http XHR completed/failed, fetch completed/failed

The number of breadcrumbs kept is capped at max_breadcrumbs (default: 20).

Sampling and deduplication

  • Sample rate: RANETRACE_JAVASCRIPT_ERRORS_SAMPLE_RATE (default 1.0 = 100%).
  • Deduplication: the script keys errors by message|filename|line|column and skips duplicates within a 50-entry rolling cache.

Ignored errors

config/ranetrace.php ships with a default ignored_errors list, including:

  • ResizeObserver loop limit exceeded / …undelivered notifications
  • Script error. / Script error (cross-origin)
  • Failed to fetch, NetworkError when attempting to fetch resource, Network request failed, Load failed
  • Loading chunk, ChunkLoadError
  • cancelled, canceled, The operation was aborted, AbortError
  • Illegal invocation

Matches are case-insensitive substring checks. Add patterns by publishing the config and extending the array.

Reporting errors manually

The script exposes two helpers on window.Ranetrace:

try {
    riskyOperation();
} catch (error) {
    window.Ranetrace.captureError(error, { payment_amount: amount });
}

window.Ranetrace.addBreadcrumb('user', 'Clicked retry', { attempt: 2 });

captureError(error, context) sends an error immediately. addBreadcrumb(category, message, data) records a breadcrumb for inclusion with the next error.

When you get notified

JavaScript errors notify you on the same cadence as PHP errors. Reports with the same message, normalized stack trace and error type are grouped into one error, and each report is an occurrence. An error notifies you:

  • on its first occurrence, so a new error never goes unseen
  • on its 5th and 10th occurrence, which tell a one-off from a pattern
  • when it starts happening 10 times within an hour after a calmer hour, however old the error is
  • when it comes back after you resolved it, even if it happens only once

An error that keeps failing at a steady rate notifies once when the burst starts, not every hour. A snoozed error stays silent until the snooze ends, and an ignored error is not recorded at all.

JavaScript errors have their own rule, separate from PHP errors, so you can switch one off and keep the other. Turn it off or on under Notify, Rules.

Testing your setup

php artisan ranetrace:test-javascript-errors

Disabling

RANETRACE_JAVASCRIPT_ERRORS_ENABLED=false

The Blade directive is safe to leave in your layout: it becomes a no-op when the feature is disabled.