# Bun (SDK tương thích Sentry)

> Dùng SDK Sentry chính thức cho Bun với DSN Belvador, bộ lọc dữ liệu của Belvador và hàng đợi trên đĩa khi node không liên lạc được.

Với máy chủ Bun, Belvador dùng **SDK Sentry chính thức cho Bun** với DSN Belvador và bộ lọc dữ liệu của chính Belvador từ `@belvador/core/sentry`. Thêm `@belvador/spool` thì lỗi chưa gửi được sẽ chờ trên đĩa tới khi node của bạn trả lời, kể cả qua một lần sập hay khởi động lại.

> [!NOTE]
> `@sentry/bun` là SDK của Sentry, không phải gói của Belvador. Belvador chạy đúng công thức này với `@sentry/bun` 11.9.0 tới một node thật: lỗi ném trong handler `Bun.serve`, lỗi chưa bắt làm sập tiến trình, và các lỗi xảy ra khi node không liên lạc được trước khi tiến trình bị kill đều tới đúng một lần.

## 1. Cài đặt

```bash
bun add @sentry/bun@11.9.0 @belvador/core@0.6.1
```

## 2. Tạo `instrument.ts`

```ts title="instrument.ts"
import * as Sentry from "@sentry/bun";
import { scrubBreadcrumb, scrubEvent } from "@belvador/core/sentry";

Sentry.init({
  dsn: process.env.BELVADOR_DSN ?? "https://<public-key>@ingest.belvador.dev/<project-id>",
  release: process.env.APP_VERSION,
  environment: process.env.NODE_ENV,
  sendDefaultPii: false,
  tracesSampleRate: 0,
  maxBreadcrumbs: 50,
  maxValueLength: 8192,
  // Belvador's scrubbing: request bodies, cookies and credentials never leave the app.
  beforeSend: scrubEvent,
  beforeBreadcrumb: scrubBreadcrumb,
});
```

Các tuỳ chọn giống [Node.js](https://belvador.dev/vi/docs/sdk/node#2-tao-instrument-mjs): SDK không gửi dữ liệu cá nhân hay span, cùng giới hạn của Belvador, và `beforeSend: scrubEvent` / `beforeBreadcrumb: scrubBreadcrumb` — bộ lọc mà SDK của Belvador chạy, nên body request, cookie, header xác thực và thông tin đăng nhập trong văn bản không rời máy chủ của bạn.

## 3. Nạp trước ứng dụng

```bash
bun --preload ./instrument.ts server.ts
```

`--preload` chạy tệp này trước entry của bạn, nên `Bun.serve` đã được gắn theo dõi khi app khởi động nó.

## Lỗi trong `Bun.serve`

```ts title="server.ts"
// An error a Bun.serve handler throws is reported by @sentry/bun; the client gets a 500.
Bun.serve({
  port: Number(process.env.PORT ?? 3000),
  async fetch(req) {
    const url = new URL(req.url);
    if (url.pathname === "/invoices") return Response.json(await listInvoices());
    return new Response("Not found", { status: 404 });
  },
});
```

Lỗi do handler `fetch` ném được `@sentry/bun` báo và client nhận `500`. Lỗi bạn tự xử lý: `Sentry.captureException(error)`.

## Giữ lỗi khi node không liên lạc được

```ts title="instrument.ts"
import * as Sentry from "@sentry/bun";
import { scrubBreadcrumb, scrubEvent } from "@belvador/core/sentry";
import { withSpool } from "@belvador/spool";

Sentry.init({
  dsn: process.env.BELVADOR_DSN ?? "https://<public-key>@ingest.belvador.dev/<project-id>",
  release: process.env.APP_VERSION,
  environment: process.env.NODE_ENV,
  sendDefaultPii: false,
  tracesSampleRate: 0,
  maxBreadcrumbs: 50,
  maxValueLength: 8192,
  // Belvador's scrubbing: request bodies, cookies and credentials never leave the app.
  beforeSend: scrubEvent,
  beforeBreadcrumb: scrubBreadcrumb,
  // Errors that cannot be sent wait on disk and go out after a restart.
  transport: withSpool(Sentry.makeFetchTransport, {
    dir: process.env.BELVADOR_SPOOL_DIR ?? "./.belvador-spool",
  }),
});
```

Lỗi chờ trong `BELVADOR_SPOOL_DIR` (tối đa 64 MiB, 72 giờ) và được tiến trình này hoặc tiến trình sau gửi khi node trả lời. Chi tiết: [Gửi bền khi mất mạng](https://belvador.dev/vi/docs/sdk/offline).

## Lỗi cơ sở dữ liệu

Kết quả `{ data, error }` từ Supabase hay PostgREST: gắn `captureResult` vào `@sentry/bun` như trong [Lỗi cơ sở dữ liệu](https://belvador.dev/vi/docs/sdk/database-errors#tren-mot-sdk-sentry-chinh-thuc), với `import * as Sentry from "@sentry/bun"`.

## Cài bằng AI agent

Dán đoạn này vào Claude Code, Cursor hay một coding agent khác. Nó chứa các tệp ở trên cùng các quy tắc agent phải theo:

````text
Belvador errors: Bun (@sentry/bun)

Tested with: @sentry/* 11.9.0
Guide: https://belvador.dev/vi/docs/sdk/bun

Mục tiêu
Báo lỗi của máy chủ này về Belvador bằng SDK Sentry chính thức và bộ lọc của Belvador, đúng như các tệp dưới đây. Không thêm SDK lỗi nào khác: mỗi tiến trình một Sentry.init.

Quy tắc
Chép nguyên các tệp và giữ mọi tuỳ chọn của Sentry.init: sendDefaultPii: false, tracesSampleRate: 0, maxBreadcrumbs: 50, beforeSend: scrubEvent, beforeBreadcrumb: scrubBreadcrumb. Đọc DSN từ BELVADOR_DSN; không tự đặt thêm biến môi trường khác. Không đổi xác thực, định tuyến hay logic nghiệp vụ. Báo những lỗi code đã tự xử lý bằng captureException (report() trên Supabase Edge Functions) và bọc bằng captureResult các kết quả Supabase hay PostgREST trả lỗi thay vì ném, không đổi cách code dùng kết quả đó.

```bash
bun add @sentry/bun@11.9.0 @belvador/core@0.6.1
```

```bash
npm install @belvador/spool@0.6.1
```

instrument.ts
```typescript
import * as Sentry from "@sentry/bun";
import { scrubBreadcrumb, scrubEvent } from "@belvador/core/sentry";
import { withSpool } from "@belvador/spool";

Sentry.init({
  dsn: process.env.BELVADOR_DSN ?? "https://<public-key>@ingest.belvador.dev/<project-id>",
  release: process.env.APP_VERSION,
  environment: process.env.NODE_ENV,
  sendDefaultPii: false,
  tracesSampleRate: 0,
  maxBreadcrumbs: 50,
  maxValueLength: 8192,
  // Belvador's scrubbing: request bodies, cookies and credentials never leave the app.
  beforeSend: scrubEvent,
  beforeBreadcrumb: scrubBreadcrumb,
  // Errors that cannot be sent wait on disk and go out after a restart.
  transport: withSpool(Sentry.makeFetchTransport, {
    dir: process.env.BELVADOR_SPOOL_DIR ?? "./.belvador-spool",
  }),
});
```

```bash
bun --preload ./instrument.ts server.ts
```

Kiểm tra
Chạy app trên máy với BELVADOR_DSN đã đặt và gây một lỗi thử (một route hay script ngắn ném lỗi). Xác nhận nó hiện thành issue trong project Belvador. Không gửi lỗi thử lên production nếu người dùng chưa đồng ý.

Báo cáo
Liệt kê các tệp đã đổi, gói đã thêm kèm đúng phiên bản, biến môi trường app giờ cần, lỗi thử bạn thấy đã tới, và những gì chưa kiểm được.
````

## Giới hạn cần biết

- Lỗi chưa bắt vẫn kết thúc tiến trình, như Bun vẫn làm khi không có SDK; lỗi được gửi trước.
- Lỗi ném trong handler của `Bun.serve` được báo và trả về 500; máy chủ vẫn tiếp tục trả lời. Bun 1.4.4 vẫn kết thúc tiến trình đó với mã thoát 1 khi dừng — có hay không có SDK — nên trình quản lý tiến trình có thể tính là lỗi.
- Belvador chưa kiểm từng tích hợp framework của Bun (Elysia, Hono); lỗi mà chúng tự biến thành phản hồi cần `Sentry.captureException`.
- Giữ `tracesSampleRate: 0`; muốn có traces thì dùng [OpenTelemetry](https://belvador.dev/vi/docs/otel/overview).
