#Exception Handling / Reporting in Convex

1 messages · Page 1 of 1 (latest)

rustic osprey
#

I know Convex provides first-party support for exception reporting/tracking in Sentry and Datadog.

I notice that some Sentry SDK options cannot be used with this. Which brings me to how can I implement my own custom handling of exceptions and errors in Convex? Is it possible?

fleet forumBOT
#

Hi @rustic osprey. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

You can customize error handling and reporting in Convex to a good extent, but only within what the platform exposes; you don’t get the raw Sentry SDK or low‑level hooks.

Here are the supported options and what you can do yourself:


1. Built‑in exception reporting (Sentry / Datadog)

Convex has a first‑party “exception reporting” integration that automatically sends all function errors (queries, mutations, actions, http actions) to Sentry or Datadog Error Tracking when enabled.[Exception reporting]

You configure this in the Dashboard → Deployment Settings → Integrations, by pasting your Sentry DSN and optional tags.[Integrations]

Convex controls how these events are sent; it:

  • Does not expose the Sentry SDK directly.
  • Automatically adds tags like func, func_type, request_id, environment, user, etc., which you cannot override.[Exception reporting]

This is why some Sentry SDK options (e.g. advanced customization, custom transport, manual spans) are not available in the built‑in integration.


2. Application‑level error handling patterns

You can fully control how your own application errors are represented and handled:

a) Return structured values (no throw)

For expected failures, you can return discriminated/structured values instead of throwing:

// Example from docs
Id<"users"> | { error: "EMAIL_ADDRESS_IN_USE" };

This keeps everything explicit and type‑safe on the client.[Application errors]

#

Note: if you want Convex’s transaction rollback in a mutation, you must throw an error rather than just returning an error value.[Application errors]

b) Throw ConvexError with structured data

For expected application errors you want to bubble up, use ConvexError:

import { ConvexError } from "convex/values";

throw new ConvexError({
  message: "My fancy error message",
  code: 123,
  severity: "high",
});

On the client you can catch and check instanceof ConvexError, then inspect error.data in a typed way.[Application errors]

Throwing in a mutation also guarantees the mutation transaction is rolled back.[Application errors]


3. Client‑side handling for query and mutation errors

You fully control how to present errors in the UI and optionally forward them to your own services:

  • Queries: errors thrown by queries propagate into React and are best handled via an error boundary. Those boundaries can send the error to any service you like (not just Sentry) in their fallback logic.[Error handling]

  • Mutations: errors reject the returned promise and roll back optimistic updates; you can .catch or use try/catch and then:

#

If you catch mutation errors yourself, they will no longer be “unhandled promise rejections”, so you may need to report them to your exception service manually.[Errors in mutations]


4. Custom observability via logs + log streams

For custom handling that doesn’t rely on Sentry/Datadog exception reporting, you can use logging:

  1. Use console.log / console.error etc. inside functions to log structured error details (including anything you’d otherwise send to Sentry).[Debugging]

  2. Enable Log Streams to send all Convex logs and function execution events to:

With a webhook log stream, Convex POSTs a JSON array of events to your URL; your own service can then:

  • Store them,
  • Run custom logic,
  • Fan out to any error‑tracking / observability stack you like.

This is the main “do‑it‑yourself” path for building a fully custom error pipeline without relying on Convex’s Sentry/Datadog integration.[Log streams common uses]


5. Other patterns & limitations

#
  • You can’t currently wire in Sentry’s distributed tracing or SDK‑level advanced options from within Convex functions; even Convex staff are unsure and recommend contacting support if you’re on Pro.[Distributed tracing thread]
  • For higher‑level production observability, Convex recommends:
    • Log Streams to Axiom/DataDog,
    • Exception reporting to Sentry,
    • And optionally using those platforms to drive alerts and dashboards.[Observability article]

Summary

  • You can implement your own exception/error handling patterns using:
    • ConvexError and structured returns in functions,
    • Client‑side error boundaries and try/catch,
    • console.* + Log Streams (including to a custom webhook you fully control).
  • You cannot currently plug in arbitrary Sentry SDK options from within Convex, nor replace Convex’s built‑in Sentry wiring, beyond the integration UI options.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@rustic osprey Kapa.ai is still learning and improving, please let me know how I did by reacting below.

rustic osprey
#

@fleet forum similarly, does Convex provide any built-in hooks for analytics?

fleet forumBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

Convex doesn’t expose a generic “analytics hook” API (like middleware or built‑in event emitters) in the same sense as its exception reporting integrations.

What is available today, based on the docs:

  • Logs + Log Streams – You can emit console.log / structured logs inside functions and stream them to Axiom, Datadog, or a custom webhook; from there, you can build dashboards, alerts, and metrics in those tools.[Log streams][Log streams uses] This is the main built‑in “hook” you’d use for analytics/observability.

  • Streaming export to analytics databases – You can stream tables to external tools (e.g. via Fivetran or Airbyte) and do OLAP‑style analytics in systems like BigQuery, Snowflake, etc.[Streaming import/export][Observability events]

  • Persist events in Convex tables – For product analytics or business events, the recommended pattern is to create an “events” table, insert structured events from your functions, and then either:

    • Query them directly in Convex, or
    • Export/stream them to an external analytics stack.[Events table]
  • Autumn integration for feature usage – If you’re using the Autumn + Convex component, there’s a built‑in autumn client you can call from backend functions (autumn.track, autumn.check) to track and gate feature usage.[Autumn backend]

#

Beyond these mechanisms, the knowledge sources don’t mention any dedicated Convex “analytics hook” APIs (like lifecycle callbacks) you can configure centrally.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: