onvibe.run

← All docs

Frontend Error Reporting

TL;DR — zero config needed

The starter app deployed by create_project already has frontend error reporting active. It wraps the handler with withErrorReporting, which auto-injects a <script> into every HTML response. No listeners to write, no client code to add.

If you wrote a custom handler, add one line:

import { withErrorReporting } from "./.onvibe/helpers.ts";

async function handler(req: Request): Promise<Response> {
  return new Response("<!DOCTYPE html>...", {
    headers: { "content-type": "text/html; charset=utf-8" },
  });
}

export default withErrorReporting(handler);  // ← this is all you need

./.onvibe/helpers.ts is injected by the platform at deploy time — do not include it in your source files.


How withErrorReporting works


The /.onvibe/exceptions endpoint

Every deployed app exposes this route at the same origin:

POST /.onvibe/exceptions
Content-Type: application/json

The runner intercepts POST /.onvibe/exceptions before passing control to your handler — no auth required from the browser (same-origin only). GET falls through to your handler.

Accepted payload fields

Field Type Description
message string Error message (required)
stack string Full stack trace as returned by err.stack
url string window.location.href at the time of the error
timestamp string ISO 8601 timestamp

Note: Fields such as source, line, col, and kind are accepted but not currently persisted separately. Include them in the stack string if you need them (e.g. src + ':' + line + ':' + col when err.stack is unavailable).

The endpoint always returns 204 No Content.


Viewing captured errors

Use get_exceptions. Each row includes a type field:

type Source
backend Unhandled server-side exception caught by the runner
frontend Browser-side JS error reported via /.onvibe/exceptions
[
  {
    "type": "frontend",
    "message": "Cannot read properties of undefined (reading 'id')",
    "stack": "TypeError: Cannot read properties of undefined...\n    at handler (https://myapp.onvibe.run/:12:5)",
    "request_url": "https://myapp.onvibe.run/dashboard",
    "occurred_at": "2025-01-01T12:00:00Z"
  }
]

Known browser limitations


Manual integration (advanced)

Only needed if you cannot use withErrorReporting (e.g. a pre-rendered static site with no server handler):

window.onerror = function(msg, src, line, col, err) {
  fetch('/.onvibe/exceptions', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      message: String(msg),
      stack: err ? err.stack : (src + ':' + line + ':' + col),
      url: window.location.href,
      timestamp: new Date().toISOString(),
    }),
  }).catch(function(){});
  return false;
};

window.addEventListener('unhandledrejection', function(e) {
  var err = e.reason;
  fetch('/.onvibe/exceptions', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      message: err instanceof Error ? err.message : String(err),
      stack: err instanceof Error ? err.stack : undefined,
      url: window.location.href,
      timestamp: new Date().toISOString(),
    }),
  }).catch(function(){});
});

Constraints

Read this page as Markdown (best for LLMs) · plain text
onvibe.run · home · all docs