Hono

Learn how to set up Sentry in your Hono app and capture your first errors.

The @sentry/hono SDK supports Hono 4+ across multiple runtimes: Cloudflare Workers, Node.js, Bun, and Deno. It works as Hono middleware, so you can drop it into your existing app with minimal setup.

Are you using @hono/sentry?

The community middleware @hono/sentry has been deprecated in favor of @sentry/hono, which provides better performance and more features. To migrate:

  1. Uninstall @hono/sentry and toucan-js
  2. Follow the install and configure steps below for your runtime
  3. Replace the old middleware with the new sentry() middleware

You need:

  • A Sentry account and project
  • Your application up and running
  • Hono version 4.0.0 or above

Choose the features you want to configure, and this guide will show you how:

Want to learn more about these features?
  • Issues (always enabled): Sentry's core error monitoring product that automatically reports errors, uncaught exceptions, and unhandled rejections. If you have something that looks like an exception, Sentry can capture it.
  • Tracing: Track software performance while seeing the impact of errors across multiple systems. For example, distributed tracing allows you to follow a request from the frontend to the backend and back.
  • Profiling: Gain deeper insight than traditional tracing without custom instrumentation, letting you discover slow-to-execute or resource-intensive functions in your app.
  • Logs: Centralize and analyze your application logs to correlate them with errors and performance issues. Search, filter, and visualize log data to understand what's happening in your applications.

Install the @sentry/hono package:

Copied
npm install @sentry/hono

The SDK needs a runtime-specific peer dependency. Install the one that matches your environment and keep its version in sync with @sentry/hono. You won't import it directly, but it must be present in your project.

Copied
npm install @sentry/cloudflare

Profiling is only available for the Node.js runtime. Install the @sentry/profiling-node package:

Copied
npm install @sentry/profiling-node --save

Cloudflare Workers: Enable Node.js Compatibility

If you're deploying to Cloudflare Workers, set the nodejs_compat compatibility flag. The SDK needs AsyncLocalStorage, which requires this flag.

wrangler.jsonc
Copied
{
  "compatibility_flags": ["nodejs_compat"],
}
Node.js: Initialize Sentry Before Your App

Node.js requires Sentry to initialize before your application loads so it can instrument third-party libraries (like database clients). Create a separate initialization file:

instrument.mjs
Copied
// IMPORTANT: import from `@sentry/hono/node`, not `@sentry/node`
import * as Sentry from "@sentry/hono/node";
// ___PRODUCT_OPTION_START___ profiling
import { nodeProfilingIntegration } from "@sentry/profiling-node";
// ___PRODUCT_OPTION_END___ profiling

Sentry.init({
  dsn: "___PUBLIC_DSN___",

  dataCollection: {
    // To disable sending user data and HTTP bodies, uncomment the lines below. For more info visit:
    // https://docs.sentry.io/platforms/javascript/guides/hono/configuration/options/#dataCollection
    // userInfo: false,
    // httpBodies: [],
  },
  // ___PRODUCT_OPTION_START___ profiling

  integrations: [nodeProfilingIntegration()],
  // ___PRODUCT_OPTION_END___ profiling
  // ___PRODUCT_OPTION_START___ performance

  // Set tracesSampleRate to 1.0 to capture 100%
  // of spans for tracing.
  // We recommend adjusting this value in production
  // Learn more at
  // https://docs.sentry.io/platforms/javascript/guides/hono/configuration/options/#tracesSampleRate
  tracesSampleRate: 1.0,
  // ___PRODUCT_OPTION_END___ performance
  // ___PRODUCT_OPTION_START___ profiling

  // Set profilesSampleRate relative to tracesSampleRate
  // Learn more at
  // https://docs.sentry.io/platforms/javascript/configuration/options/#profileSessionSampleRate
  profileSessionSampleRate: 1.0,
  // ___PRODUCT_OPTION_END___ profiling
  // ___PRODUCT_OPTION_START___ logs

  // Enable logs to be sent to Sentry
  enableLogs: true,
  // ___PRODUCT_OPTION_END___ logs
});

Load this file with the --import flag when starting your app. You can also set this as an environment variable instead:

Copied
node --import ./instrument.mjs app.js

Add the sentry() middleware as early as possible in your Hono app.

Before continuing, make sure you've completed the runtime-specific steps above: Cloudflare Workers users need to enable Node.js compatibility, and Node.js users need to create the instrument file. Since Node.js initializes Sentry in that file, the middleware doesn't take any options.

index.ts
Copied
import { Hono } from "hono";
import { sentry } from "@sentry/hono/cloudflare";

const app = new Hono();

app.use(
  sentry(app, {
    dsn: "___PUBLIC_DSN___",

    dataCollection: {
      // To disable sending user data and HTTP bodies, uncomment the lines below. For more info visit:
      // https://docs.sentry.io/platforms/javascript/guides/hono/configuration/options/#dataCollection
      // userInfo: false,
      // httpBodies: [],
    },
    // ___PRODUCT_OPTION_START___ performance

    // Set tracesSampleRate to 1.0 to capture 100%
    // of spans for tracing.
    tracesSampleRate: 1.0,
    // ___PRODUCT_OPTION_END___ performance
    // ___PRODUCT_OPTION_START___ logs

    // Enable logs to be sent to Sentry
    enableLogs: true,
    // ___PRODUCT_OPTION_END___ logs
  }),
);

// Your routes here

export default app;
Cloudflare Workers: Accessing env from Worker Bindings

To access environment variables from your Cloudflare Worker bindings (for example, to store the DSN as a secret), pass a callback instead of a plain options object. The function receives the Worker env:

index.ts
Copied
import { Hono } from "hono";
import { sentry } from "@sentry/hono/cloudflare";

type Bindings = { SENTRY_DSN: string };

const app = new Hono<{ Bindings: Bindings }>();

app.use(sentry(app, (env) => ({ dsn: env.SENTRY_DSN })));

export default app;

By default, Sentry captures exceptions from Hono's onError handler, excluding errors with 3xx or 4xx status codes. No additional configuration is needed for this.

To control which errors are captured, use the shouldHandleError option.

The stack traces in your Sentry errors probably won't look like your actual code without unminifying them. To fix this, upload your source maps to Sentry. The easiest way to do this is by using the Sentry Wizard.

Alternatively, take a look at our Uploading Source Maps documentation.

Copied
npx @sentry/wizard@latest -i sourcemaps

First, let's verify that Sentry captures errors and creates issues in your Sentry project. Add the following code snippet to your main application file, adding a route that triggers an error that Sentry will capture:

Copied
app.get("/debug-sentry", () => {
  throw new Error("My first Sentry error!");
});

To test your tracing configuration, update the previous code snippet by starting a trace to measure the time it takes for the execution of your code:

Copied
app.get("/debug-sentry", async () => {
  await Sentry.startSpan(
    {
      op: "test",
      name: "My First Test Transaction",
    },
    async () => {
      await new Promise((resolve) => setTimeout(resolve, 100)); // Wait for 100ms
      throw new Error("My first Sentry error!");
    },
  );
});

To verify that Sentry catches your logs, add some log statements to your application:

Copied
Sentry.logger.info("User example action completed");

Sentry.logger.warn("Slow operation detected", {
  operation: "data_fetch",
  duration: 3500,
});

Sentry.logger.error("Validation failed", {
  field: "email",
  reason: "Invalid email",
});

Now, head over to your project on Sentry.io to view the collected data (it takes a couple of moments for the data to appear).

Need help locating the captured errors in your Sentry project?
  • Open the Issues page and select an error from the issues list to view the full details and context of this error. For more details, see this interactive walkthrough.
  • Open the Traces page and select a trace to reveal more information about each span, its duration, and any errors. For an interactive UI walkthrough, click here.
  • Open the Profiles page, select a transaction, and then a profile ID to view its flame graph. For more information, click here.
  • Open the Logs page and filter by service, environment, or search keywords to view log entries from your application. For an interactive UI walkthrough, click here.

At this point, you should have Sentry integrated into your Hono application and already be sending data to your Sentry project.

Now's a good time to customize your setup and look into more advanced topics:

Are you having problems setting up the SDK?
Was this helpful?
Help improve this content
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").