Skip to main content
The Sentry Deno SDK is in Beta. Please help us improve the SDK by reporting issues or giving feedback.
The Sentry Deno SDK provides error monitoring and performance tracking for applications running on the Deno runtime.

Installation

Import the SDK from npm using Deno’s npm specifier:
import * as Sentry from 'npm:@sentry/deno';
Or add to your import map:
// 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
});
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
Recommended permissions:
deno run \
  --allow-net=sentry.io,ingest.sentry.io \
  --allow-env=SENTRY_DSN,SENTRY_ENVIRONMENT \
  --allow-read \
  main.ts

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!');
    },
  );
});
Set environment variable in 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

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 });
  }
});

Next Steps

Deno Documentation

Official Deno documentation

Deno Deploy

Deploy to Deno Deploy

Performance

Performance monitoring guide

Source Maps

Source maps configuration

Build docs developers (and LLMs) love