The Sentry Deno SDK is in Beta. Please help us improve the SDK by reporting issues or giving feedback.
Installation
Import the SDK from npm using Deno’s npm specifier:import * as Sentry from 'npm:@sentry/deno';
// deno.json
{
"imports": {
"@sentry/deno": "npm:@sentry/deno@^8.0.0"
}
}
Basic Setup
Initialize Sentry at the top of your main module:import * as Sentry from 'npm:@sentry/deno';
Sentry.init({
dsn: 'YOUR_DSN_HERE',
// Performance Monitoring
tracesSampleRate: 1.0,
// Set tracesSampleRate to 1.0 to capture 100%
// of transactions for performance monitoring.
// We recommend adjusting this value in production.
});
// Your application code
Deno.serve({ port: 3000 }, (req) => {
return new Response('Hello from Deno!');
});
Deno.serve Integration
Monitor your Deno HTTP server:import * as Sentry from 'npm:@sentry/deno';
Sentry.init({
dsn: 'YOUR_DSN_HERE',
tracesSampleRate: 1.0,
});
Deno.serve({ port: 3000 }, async (req) => {
try {
const url = new URL(req.url);
// Add request context
Sentry.setContext('request', {
method: req.method,
path: url.pathname,
});
// Route handling
if (url.pathname === '/') {
return new Response('Hello World!');
}
if (url.pathname === '/error') {
throw new Error('Test error');
}
return new Response('Not Found', { status: 404 });
} catch (error) {
Sentry.captureException(error);
return new Response('Internal Server Error', { status: 500 });
}
});
Error Tracking
Automatic Error Capture
import * as Sentry from 'npm:@sentry/deno';
Sentry.init({
dsn: 'YOUR_DSN_HERE',
});
// Uncaught errors are automatically captured
throw new Error('This will be captured');
Manual Error Capture
import * as Sentry from 'npm:@sentry/deno';
try {
await riskyOperation();
} catch (error) {
Sentry.captureException(error, {
tags: {
module: 'data-processor',
},
extra: {
operationType: 'import',
},
});
}
// Capture messages
Sentry.captureMessage('Something unexpected happened', 'warning');
Performance Monitoring
Custom Spans
import * as Sentry from 'npm:@sentry/deno';
Deno.serve(async (req) => {
return await Sentry.startSpan(
{
name: 'http.server',
op: 'http.server',
attributes: {
'http.method': req.method,
'http.url': req.url,
},
},
async () => {
const data = await Sentry.startSpan(
{ name: 'fetch-data', op: 'db.query' },
async () => {
return await fetchDataFromKV();
},
);
return Response.json(data);
},
);
});
Nested Spans
import * as Sentry from 'npm:@sentry/deno';
await Sentry.startSpan(
{ name: 'process-request', op: 'function' },
async () => {
await Sentry.startSpan(
{ name: 'validate-input', op: 'function' },
async () => {
await validateInput(data);
},
);
await Sentry.startSpan(
{ name: 'process-data', op: 'function' },
async () => {
await processData(data);
},
);
await Sentry.startSpan(
{ name: 'send-response', op: 'http.client' },
async () => {
await fetch('https://api.example.com/callback', {
method: 'POST',
body: JSON.stringify(result),
});
},
);
},
);
Context & User Information
Set User Context
import * as Sentry from 'npm:@sentry/deno';
Sentry.setUser({
id: '123',
email: '[email protected]',
username: 'john_doe',
});
// Clear user context
Sentry.setUser(null);
Add Custom Context
import * as Sentry from 'npm:@sentry/deno';
Deno.serve(async (req) => {
// Set context for this request
Sentry.setContext('request', {
method: req.method,
headers: Object.fromEntries(req.headers),
});
Sentry.setTag('deno_version', Deno.version.deno);
Sentry.setTag('environment', 'production');
// Your handler code
});
Breadcrumbs
import * as Sentry from 'npm:@sentry/deno';
Sentry.addBreadcrumb({
category: 'auth',
message: 'User authenticated',
level: 'info',
data: {
userId: '123',
method: 'oauth',
},
});
Deno KV Integration
Track Deno KV operations:import * as Sentry from 'npm:@sentry/deno';
const kv = await Deno.openKv();
// Wrap KV operations with spans
const value = await Sentry.startSpan(
{
name: 'kv.get',
op: 'db.query',
attributes: {
'db.system': 'deno-kv',
'db.operation': 'get',
},
},
async () => {
try {
const result = await kv.get(['users', userId]);
return result.value;
} catch (error) {
Sentry.captureException(error);
throw error;
}
},
);
HTTP Client Tracking
import * as Sentry from 'npm:@sentry/deno';
const data = await Sentry.startSpan(
{
name: 'GET https://api.example.com/data',
op: 'http.client',
attributes: {
'http.method': 'GET',
'http.url': 'https://api.example.com/data',
},
},
async () => {
try {
const response = await fetch('https://api.example.com/data');
Sentry.setTag('http.status_code', response.status);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return await response.json();
} catch (error) {
Sentry.captureException(error);
throw error;
}
},
);
File System Operations
import * as Sentry from 'npm:@sentry/deno';
const content = await Sentry.startSpan(
{
name: 'read file',
op: 'file.read',
attributes: {
'file.path': './data.json',
},
},
async () => {
try {
return await Deno.readTextFile('./data.json');
} catch (error) {
Sentry.captureException(error);
throw error;
}
},
);
WebSocket Support
import * as Sentry from 'npm:@sentry/deno';
Deno.serve((req) => {
if (req.headers.get('upgrade') === 'websocket') {
const { socket, response } = Deno.upgradeWebSocket(req);
socket.onopen = () => {
Sentry.addBreadcrumb({
category: 'websocket',
message: 'Client connected',
level: 'info',
});
};
socket.onmessage = (event) => {
try {
Sentry.startSpan(
{ name: 'websocket.message', op: 'websocket' },
() => {
handleMessage(socket, event.data);
},
);
} catch (error) {
Sentry.captureException(error);
}
};
socket.onerror = (error) => {
Sentry.captureException(error, {
tags: { type: 'websocket' },
});
};
return response;
}
return new Response('WebSocket server', { status: 200 });
});
Cron Monitoring
import * as Sentry from 'npm:@sentry/deno';
Deno.cron('cleanup', '0 * * * *', async () => {
await Sentry.withMonitor(
'cleanup-job',
async () => {
await performCleanup();
},
{
schedule: {
type: 'crontab',
value: '0 * * * *',
},
checkinMargin: 5,
maxRuntime: 30,
},
);
});
Permissions
The Sentry SDK requires certain Deno permissions:# Network access to send events to Sentry
deno run --allow-net=sentry.io main.ts
# Environment variables for configuration
deno run --allow-env=SENTRY_DSN main.ts
# File system for source maps
deno run --allow-read main.ts
deno run \
--allow-net=sentry.io,ingest.sentry.io \
--allow-env=SENTRY_DSN,SENTRY_ENVIRONMENT \
--allow-read \
main.ts
Configuration
Complete Configuration
Complete Configuration
import * as Sentry from 'npm:@sentry/deno';
Sentry.init({
dsn: 'YOUR_DSN_HERE',
// Environment
environment: Deno.env.get('ENVIRONMENT') || 'development',
release: Deno.env.get('VERSION'),
serverName: Deno.env.get('HOSTNAME'),
// Performance
tracesSampleRate: 0.2,
// Error filtering
ignoreErrors: [
'ConnectionReset',
'BrokenPipe',
],
beforeSend(event, hint) {
// Filter or modify events
if (event.request) {
// Remove sensitive data
delete event.request.cookies;
delete event.request.headers?.['authorization'];
}
return event;
},
beforeBreadcrumb(breadcrumb, hint) {
// Filter or modify breadcrumbs
if (breadcrumb.category === 'console') {
return null;
}
return breadcrumb;
},
});
Deno Deploy
Deploy to Deno Deploy with Sentry:// main.ts
import * as Sentry from 'npm:@sentry/deno';
Sentry.init({
dsn: Deno.env.get('SENTRY_DSN'),
environment: 'production',
tracesSampleRate: 0.1,
});
Deno.serve(async (req) => {
return await Sentry.startSpan(
{ name: 'http.server', op: 'http.server' },
async () => {
// Your handler code
return new Response('Hello from Deno Deploy!');
},
);
});
SENTRY_DSN=your-dsn-here
Best Practices
Initialize Early
Call
Sentry.init() at the top of your main module.Use Spans
Wrap important operations with spans to track performance.
Set Permissions
Grant only the necessary permissions to Sentry.
Environment Config
Use environment variables for configuration.
Common Patterns
- REST API
- Scheduled Tasks
import * as Sentry from 'npm:@sentry/deno';
Sentry.init({ dsn: 'YOUR_DSN_HERE' });
const routes = new Map([
['/api/users', handleUsers],
['/api/posts', handlePosts],
]);
Deno.serve(async (req) => {
const url = new URL(req.url);
const handler = routes.get(url.pathname);
if (!handler) {
return new Response('Not Found', { status: 404 });
}
try {
return await Sentry.startSpan(
{
name: `${req.method} ${url.pathname}`,
op: 'http.server',
},
() => handler(req),
);
} catch (error) {
Sentry.captureException(error);
return new Response('Error', { status: 500 });
}
});
import * as Sentry from 'npm:@sentry/deno';
Sentry.init({ dsn: 'YOUR_DSN_HERE' });
Deno.cron('daily-report', '0 9 * * *', async () => {
await Sentry.withMonitor('daily-report', async () => {
await generateDailyReport();
});
});
Deno.cron('hourly-sync', '0 * * * *', async () => {
await Sentry.withMonitor('hourly-sync', async () => {
await syncData();
});
});
Next Steps
Deno Documentation
Official Deno documentation
Deno Deploy
Deploy to Deno Deploy
Performance
Performance monitoring guide
Source Maps
Source maps configuration