Send browser JavaScript errors to Kibana

Capture browser errors and rejected promises, send them through a controlled collection endpoint, and analyze them in Kibana.

Best practices
Log monitoring illustration

Capture browser errors, send them to a controlled application endpoint, and let the backend write them to Elasticsearch directly or through a collector. Kibana reads the indexed events. Do not expose Elasticsearch write credentials in browser JavaScript.

Capture runtime errors and unhandled rejections

function reportError(details) {
  const event = {
    ...details,
    pagePath: window.location.pathname,
    userAgent: navigator.userAgent,
    timestamp: new Date().toISOString()
  };
  fetch('/api/log-error', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(event)
  }).catch(() => {});
}

window.addEventListener('error', (event) => {
  reportError({
    type: 'error',
    message: String(event.message || 'Unknown script error'),
    source: event.filename,
    lineno: event.lineno,
    colno: event.colno,
    stack: event.error && event.error.stack
  });
});

window.addEventListener('unhandledrejection', (event) => {
  const reason = event.reason;
  reportError({
    type: 'unhandledrejection',
    message: reason instanceof Error ? reason.message : String(reason),
    stack: reason instanceof Error ? reason.stack : undefined
  });
});

Using an event listener avoids replacing an application's existing window.onerror handler. Promise rejections can contain strings, numbers, or other values rather than an Error, so handle those cases too. This example avoids sending URL query parameters, but paths, messages, source URLs, and stacks can still contain sensitive data; redact them according to your application's rules.

Validate events on the backend

The collection endpoint should validate the schema, cap payload sizes, rate-limit submissions, and add trusted server metadata. Treat client-provided values as untrusted. Use an ingest pipeline or backend transformation to create a date-mapped @timestamp, and map fields consistently before volume grows.

Create a Kibana data view for the destination index or data stream. Select its time field, then filter by error type, release, page, and browser. Do not recursively report a failure of the error-reporting endpoint itself.

Know the capture and delivery limits

Global error handlers do not capture every failure. Handled exceptions, some resource failures, and cross-origin restrictions need separate consideration. Cross-origin script diagnostics may require both the script's crossorigin attribute and suitable CORS response headers.

navigator.sendBeacon() can help send small payloads around page lifecycle transitions, but it only confirms that a request was queued, not delivered. Neither it nor fetch guarantees delivery when the page closes. Batching, sampling, payload caps, and a tested lifecycle strategy matter more than replacing one call blindly.

For readable production stacks, match source maps to the exact release and asset URL through an error-monitoring workflow. Kibana does not symbolicate arbitrary log strings merely because a source map exists.

References: unhandled rejections and sendBeacon behavior. Guance's Web RUM integration offers an alternative collection path for browser monitoring.

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting