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.
You need:
Choose the features you want to configure, and this guide will show you how:
Install the @sentry/hono package:
npm install @sentry/hono
npm install @sentry/hono
yarn add @sentry/hono
pnpm add @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.
npm install @sentry/cloudflare
npm install @sentry/cloudflare
npm install @sentry/node
npm install @sentry/bun
deno add npm:@sentry/deno
Profiling is only available for the Node.js runtime. Install the @sentry/profiling-node package:
npm install @sentry/profiling-node --save
npm install @sentry/profiling-node --save
yarn add @sentry/profiling-node
pnpm add @sentry/profiling-node
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.tsimport { 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;
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;
import { Hono } from "hono";
import { serve } from "@hono/node-server";
import { sentry } from "@sentry/hono/node";
const app = new Hono();
app.use(sentry(app));
// Your routes here
serve(app);
import { Hono } from "hono";
import { sentry } from "@sentry/hono/bun";
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;
import { Hono } from "hono";
import { sentry } from "@sentry/hono/deno";
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
Deno.serve(app.fetch);
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.
npx @sentry/wizard@latest -i sourcemaps
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:
app.get("/debug-sentry", () => {
throw new Error("My first Sentry error!");
});
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:
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!");
},
);
});
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:
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",
});
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).
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:
- Explore practical guides on what to monitor, log, track, and investigate after setup
- Learn how to manually capture errors
- Explore Hono-specific features like custom error filtering
- Continue to customize your configuration
- Get familiar with Sentry's product features like tracing, insights, and alerts
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").