# Framework Integrations

Auto-instrumentation for popular Node.js web frameworks including Express, Fastify, Koa, and Hapi.

## Capabilities

### Express.js Integration

Automatic instrumentation and error handling for Express.js applications.

```typescript { .api }
/**
 * Create Express.js integration for automatic instrumentation
 * @param options - Express integration configuration options
 * @returns Express integration instance
 */
function expressIntegration(options?: ExpressOptions): Integration;

/**
 * Create Express error handler middleware
 * @param options - Error handler configuration options
 * @returns Express error handler middleware
 */
function expressErrorHandler(options?: ExpressErrorHandlerOptions): RequestHandler;

/**
 * Setup Express error handler on an Express app
 * @param app - Express application instance
 * @param options - Error handler configuration options
 */
function setupExpressErrorHandler(app: Express, options?: ExpressErrorHandlerOptions): void;
```

**Usage Examples:**

```typescript
import * as Sentry from "@sentry/node";
import express from "express";

// Initialize with Express integration
Sentry.init({
  dsn: "YOUR_DSN",
  integrations: [
    Sentry.expressIntegration({
      router: true, // Capture router layer info
      user: ["id", "username", "email"], // User keys to capture
    }),
  ],
});

const app = express();

// Setup error handler
Sentry.setupExpressErrorHandler(app, {
  shouldHandleError: (error) => {
    // Only handle 5xx errors
    return error.status >= 500;
  },
});

// Or use error handler middleware directly
app.use(Sentry.expressErrorHandler({
  shouldHandleError: (error) => error.status >= 500,
}));

// Manual Express setup with middleware
app.use((req, res, next) => {
  // Request will be automatically traced
  next();
});

app.get("/users/:id", (req, res) => {
  // Route info automatically captured
  const user = getUserById(req.params.id);
  res.json(user);
});

// Error handler should be last middleware
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send("Something broke!");
});
```

### Fastify Integration

Automatic instrumentation and error handling for Fastify applications.

```typescript { .api }
/**
 * Create Fastify integration for automatic instrumentation
 * @param options - Fastify integration configuration options
 * @returns Fastify integration instance
 */
function fastifyIntegration(options?: FastifyOptions): Integration;

/**
 * Setup Fastify error handler
 * @param app - Fastify instance
 * @param options - Error handler configuration options
 */
function setupFastifyErrorHandler(app: FastifyInstance, options?: FastifyErrorHandlerOptions): void;
```

**Usage Examples:**

```typescript
import * as Sentry from "@sentry/node";
import Fastify from "fastify";

// Initialize with Fastify integration
Sentry.init({
  dsn: "YOUR_DSN",
  integrations: [
    Sentry.fastifyIntegration({
      extractRequestData: ["headers", "method", "url", "query_string"],
    }),
  ],
});

const fastify = Fastify({ logger: true });

// Setup error handler
Sentry.setupFastifyErrorHandler(fastify, {
  shouldHandleError: (error) => error.statusCode >= 500,
});

// Register routes
fastify.get("/users/:id", async (request, reply) => {
  // Route automatically traced
  const user = await getUserById(request.params.id);
  return user;
});

// Error handling
fastify.setErrorHandler(async (error, request, reply) => {
  // Errors automatically captured by Sentry
  reply.status(500).send({ error: "Internal Server Error" });
});

const start = async () => {
  try {
    await fastify.listen({ port: 3000 });
  } catch (err) {
    fastify.log.error(err);
    process.exit(1);
  }
};
start();
```

### Koa.js Integration

Automatic instrumentation and error handling for Koa.js applications.

```typescript { .api }
/**
 * Create Koa.js integration for automatic instrumentation
 * @param options - Koa integration configuration options
 * @returns Koa integration instance
 */
function koaIntegration(options?: KoaOptions): Integration;

/**
 * Setup Koa error handler
 * @param app - Koa application instance
 * @param options - Error handler configuration options
 */
function setupKoaErrorHandler(app: KoaApp, options?: KoaErrorHandlerOptions): void;
```

**Usage Examples:**

```typescript
import * as Sentry from "@sentry/node";
import Koa from "koa";
import Router from "@koa/router";

// Initialize with Koa integration
Sentry.init({
  dsn: "YOUR_DSN",
  integrations: [
    Sentry.koaIntegration({
      extractRequestData: ["headers", "method", "url", "query"],
    }),
  ],
});

const app = new Koa();
const router = new Router();

// Setup error handler
Sentry.setupKoaErrorHandler(app, {
  shouldHandleError: (error) => error.status >= 500,
});

// Error handling middleware
app.on("error", (err, ctx) => {
  // Errors automatically captured by Sentry
  console.error("Server error:", err, ctx);
});

// Routes
router.get("/users/:id", async (ctx) => {
  // Route automatically traced
  const user = await getUserById(ctx.params.id);
  ctx.body = user;
});

app.use(router.routes()).use(router.allowedMethods());

app.listen(3000);
```

### Hapi.js Integration

Automatic instrumentation and error handling for Hapi.js applications.

```typescript { .api }
/**
 * Create Hapi.js integration for automatic instrumentation
 * @param options - Hapi integration configuration options
 * @returns Hapi integration instance
 */
function hapiIntegration(options?: HapiOptions): Integration;

/**
 * Setup Hapi error handler
 * @param server - Hapi server instance
 * @param options - Error handler configuration options
 */
function setupHapiErrorHandler(server: HapiServer, options?: HapiErrorHandlerOptions): void;
```

**Usage Examples:**

```typescript
import * as Sentry from "@sentry/node";
import Hapi from "@hapi/hapi";

// Initialize with Hapi integration
Sentry.init({
  dsn: "YOUR_DSN",
  integrations: [
    Sentry.hapiIntegration({
      extractRequestData: ["headers", "method", "url", "query"],
    }),
  ],
});

const init = async () => {
  const server = Hapi.server({
    port: 3000,
    host: "localhost",
  });

  // Setup error handler
  Sentry.setupHapiErrorHandler(server, {
    shouldHandleError: (error) => error.output?.statusCode >= 500,
  });

  // Route
  server.route({
    method: "GET",
    path: "/users/{id}",
    handler: async (request, h) => {
      // Route automatically traced
      const user = await getUserById(request.params.id);
      return user;
    },
  });

  // Error handling
  server.ext("onPreResponse", (request, h) => {
    const response = request.response;
    if (response.isBoom && response.output.statusCode >= 500) {
      // Error automatically captured by Sentry
      console.error("Server error:", response);
    }
    return h.continue;
  });

  await server.start();
  console.log("Server running on %s", server.info.uri);
};

init();
```

### Connect Middleware Integration

Automatic instrumentation for Connect middleware.

```typescript { .api }
/**
 * Create Connect integration for automatic instrumentation
 * @param options - Connect integration configuration options
 * @returns Connect integration instance
 */
function connectIntegration(options?: ConnectOptions): Integration;

/**
 * Setup Connect error handler
 * @param app - Connect app instance
 * @param options - Error handler configuration options
 */
function setupConnectErrorHandler(app: ConnectApp, options?: ConnectErrorHandlerOptions): void;
```

**Usage Examples:**

```typescript
import * as Sentry from "@sentry/node";
import connect from "connect";

// Initialize with Connect integration
Sentry.init({
  dsn: "YOUR_DSN",
  integrations: [
    Sentry.connectIntegration({
      extractRequestData: ["headers", "method", "url"],
    }),
  ],
});

const app = connect();

// Setup error handler
Sentry.setupConnectErrorHandler(app, {
  shouldHandleError: (error) => true,
});

// Middleware
app.use("/api", (req, res, next) => {
  // Request automatically traced
  if (req.url === "/users") {
    res.end("Users endpoint");
  } else {
    next();
  }
});

// Error middleware
app.use((err, req, res, next) => {
  // Errors automatically captured
  res.statusCode = 500;
  res.end("Internal Server Error");
});

app.listen(3000);
```

### HTTP Integration

General HTTP instrumentation for outgoing requests.

```typescript { .api }
/**
 * Create HTTP integration for outgoing request instrumentation
 * @param options - HTTP integration configuration options
 * @returns HTTP integration instance
 */
function httpIntegration(options?: HttpIntegrationOptions): Integration;

/**
 * Create Node.js fetch integration for fetch API instrumentation
 * @param options - Node fetch configuration options
 * @returns Node fetch integration instance
 */
function nativeNodeFetchIntegration(options?: NodeFetchOptions): Integration;
```

**Usage Examples:**

```typescript
import * as Sentry from "@sentry/node";

// Initialize with HTTP integrations
Sentry.init({
  dsn: "YOUR_DSN",
  integrations: [
    Sentry.httpIntegration({
      breadcrumbs: true, // Add breadcrumbs for HTTP requests
      tracing: true, // Create spans for HTTP requests
    }),
    Sentry.nativeNodeFetchIntegration({
      breadcrumbs: true,
      tracing: true,
    }),
  ],
});

// HTTP requests will be automatically traced
import http from "http";
import https from "https";

// This request will create a span
const req = https.request("https://api.example.com/data", (res) => {
  let data = "";
  res.on("data", (chunk) => {
    data += chunk;
  });
  res.on("end", () => {
    console.log("Response:", data);
  });
});
req.end();

// Fetch requests will also be traced
fetch("https://api.example.com/users")
  .then((response) => response.json())
  .then((data) => console.log(data));
```

## Types

### Integration Options

```typescript { .api }
interface ExpressOptions {
  /** Include router information in spans */
  router?: boolean;
  /** User properties to extract from req.user */
  user?: string[] | boolean;
  /** Request data to extract */
  extractRequestData?: string[];
}

interface ExpressErrorHandlerOptions {
  /** Function to determine if error should be handled */
  shouldHandleError?: (error: any) => boolean;
  /** Additional data to attach to events */
  attachEventData?: (event: Event, request: Request) => Event;
}

interface FastifyOptions {
  /** Request data to extract */
  extractRequestData?: string[];
}

interface FastifyErrorHandlerOptions {
  /** Function to determine if error should be handled */
  shouldHandleError?: (error: any) => boolean;
}

interface KoaOptions {
  /** Request data to extract */
  extractRequestData?: string[];
}

interface KoaErrorHandlerOptions {
  /** Function to determine if error should be handled */
  shouldHandleError?: (error: any) => boolean;
}

interface HapiOptions {
  /** Request data to extract */
  extractRequestData?: string[];
}

interface HapiErrorHandlerOptions {
  /** Function to determine if error should be handled */
  shouldHandleError?: (error: any) => boolean;
}

interface ConnectOptions {
  /** Request data to extract */
  extractRequestData?: string[];
}

interface ConnectErrorHandlerOptions {
  /** Function to determine if error should be handled */
  shouldHandleError?: (error: any) => boolean;
}
```

### HTTP Integration Options

```typescript { .api }
interface HttpIntegrationOptions {
  /** Add breadcrumbs for HTTP requests */
  breadcrumbs?: boolean;
  /** Create spans for HTTP requests */
  tracing?: boolean;
  /** URL patterns to ignore */
  ignoreUrls?: (string | RegExp)[];
  /** HTTP status codes to consider as errors */
  failedRequestStatusCodes?: [number, number][];
  /** HTTP status codes for successful requests */
  successfulRequestStatusCodes?: [number, number][];
}

interface NodeFetchOptions {
  /** Add breadcrumbs for fetch requests */
  breadcrumbs?: boolean;
  /** Create spans for fetch requests */
  tracing?: boolean;
  /** URL patterns to ignore */
  ignoreUrls?: (string | RegExp)[];
  /** HTTP status codes to consider as errors */
  failedRequestStatusCodes?: [number, number][];
  /** HTTP status codes for successful requests */
  successfulRequestStatusCodes?: [number, number][];
}
```

### Framework Types

```typescript { .api }
type RequestHandler = (req: any, res: any, next: any) => void;
type Express = any; // Express application instance
type FastifyInstance = any; // Fastify instance
type KoaApp = any; // Koa application instance
type HapiServer = any; // Hapi server instance
type ConnectApp = any; // Connect application instance
```