Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .craft.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ targets:
- name: npm
id: '@sentry/bun'
includeNames: /^sentry-bun-\d.*\.tgz$/
- name: npm
id: '@sentry/elysia'
includeNames: /^sentry-elysia-\d.*\.tgz$/
- name: npm
id: '@sentry/hono'
includeNames: /^sentry-hono-\d.*\.tgz$/
Expand Down Expand Up @@ -246,3 +249,8 @@ targets:
sdkName: 'sentry.javascript.effect'
packageUrl: 'https://www.npmjs.com/package/@sentry/effect'
onlyIfPresent: /^sentry-effect-\d.*\.tgz$/
'npm:@sentry/elysia':
name: 'Sentry Elysia SDK'
packageUrl: 'https://www.npmjs.com/package/@sentry/elysia'
mainDocsUrl: 'https://docs.sentry.io/platforms/javascript/guides/elysia/'
onlyIfPresent: /^sentry-elysia-\d.*\.tgz$/
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/bug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ body:
- '@sentry/cloudflare - hono'
- '@sentry/deno'
- '@sentry/effect'
- '@sentry/elysia'
- '@sentry/ember'
- '@sentry/gatsby'
- '@sentry/google-cloud-serverless'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -961,7 +961,7 @@ jobs:
with:
node-version-file: 'dev-packages/e2e-tests/test-applications/${{ matrix.test-application }}/package.json'
- name: Set up Bun
if: contains(fromJSON('["node-exports-test-app","nextjs-16-bun"]'), matrix.test-application)
if: contains(fromJSON('["node-exports-test-app","nextjs-16-bun", "elysia-bun"]'), matrix.test-application)
uses: oven-sh/setup-bun@v2
- name: Set up AWS SAM
if: matrix.test-application == 'aws-serverless'
Expand Down
26 changes: 13 additions & 13 deletions .size-limit.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ module.exports = [
name: 'CDN Bundle (incl. Tracing)',
path: createCDNPath('bundle.tracing.min.js'),
gzip: true,
limit: '44 KB',
limit: '45 KB',
},
{
name: 'CDN Bundle (incl. Logs, Metrics)',
Expand All @@ -196,37 +196,37 @@ module.exports = [
name: 'CDN Bundle (incl. Tracing, Logs, Metrics)',
path: createCDNPath('bundle.tracing.logs.metrics.min.js'),
gzip: true,
limit: '45 KB',
limit: '46 KB',
},
{
name: 'CDN Bundle (incl. Replay, Logs, Metrics)',
path: createCDNPath('bundle.replay.logs.metrics.min.js'),
gzip: true,
limit: '69 KB',
limit: '70 KB',
},
{
name: 'CDN Bundle (incl. Tracing, Replay)',
path: createCDNPath('bundle.tracing.replay.min.js'),
gzip: true,
limit: '81 KB',
limit: '82 KB',
},
{
name: 'CDN Bundle (incl. Tracing, Replay, Logs, Metrics)',
path: createCDNPath('bundle.tracing.replay.logs.metrics.min.js'),
gzip: true,
limit: '82 KB',
limit: '83 KB',
},
{
name: 'CDN Bundle (incl. Tracing, Replay, Feedback)',
path: createCDNPath('bundle.tracing.replay.feedback.min.js'),
gzip: true,
limit: '86 KB',
limit: '88 KB',
},
{
name: 'CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics)',
path: createCDNPath('bundle.tracing.replay.feedback.logs.metrics.min.js'),
gzip: true,
limit: '87 KB',
limit: '88 KB',
},
// browser CDN bundles (non-gzipped)
{
Expand All @@ -241,7 +241,7 @@ module.exports = [
path: createCDNPath('bundle.tracing.min.js'),
gzip: false,
brotli: false,
limit: '129 KB',
limit: '133 KB',
},
{
name: 'CDN Bundle (incl. Logs, Metrics) - uncompressed',
Expand All @@ -255,28 +255,28 @@ module.exports = [
path: createCDNPath('bundle.tracing.logs.metrics.min.js'),
gzip: false,
brotli: false,
limit: '132 KB',
limit: '136 KB',
},
{
name: 'CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed',
path: createCDNPath('bundle.replay.logs.metrics.min.js'),
gzip: false,
brotli: false,
limit: '210 KB',
limit: '212 KB',
},
{
name: 'CDN Bundle (incl. Tracing, Replay) - uncompressed',
path: createCDNPath('bundle.tracing.replay.min.js'),
gzip: false,
brotli: false,
limit: '246 KB',
limit: '250 KB',
},
{
name: 'CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed',
path: createCDNPath('bundle.tracing.replay.logs.metrics.min.js'),
gzip: false,
brotli: false,
limit: '250 KB',
limit: '253 KB',
},
{
name: 'CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed',
Expand All @@ -290,7 +290,7 @@ module.exports = [
path: createCDNPath('bundle.tracing.replay.feedback.logs.metrics.min.js'),
gzip: false,
brotli: false,
limit: '264 KB',
limit: '266 KB',
},
// Next.js SDK (ESM)
{
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ package. Please refer to the README and instructions of those SDKs for more deta
for native crashes
- [`@sentry/effect`](https://github.com/getsentry/sentry-javascript/tree/master/packages/effect): SDK for Effect (Alpha)
- [`@sentry/bun`](https://github.com/getsentry/sentry-javascript/tree/master/packages/bun): SDK for Bun
- [`@sentry/elysia`](https://github.com/getsentry/sentry-javascript/tree/master/packages/elysia): SDK for Elysia
- [`@sentry/deno`](https://github.com/getsentry/sentry-javascript/tree/master/packages/deno): SDK for Deno
- [`@sentry/cloudflare`](https://github.com/getsentry/sentry-javascript/tree/master/packages/cloudflare): SDK for
Cloudflare
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist
2 changes: 2 additions & 0 deletions dev-packages/e2e-tests/test-applications/elysia-bun/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@sentry:registry=http://127.0.0.1:4873
@sentry-internal:registry=http://127.0.0.1:4873
26 changes: 26 additions & 0 deletions dev-packages/e2e-tests/test-applications/elysia-bun/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "elysia-bun-app",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"start": "bun src/app.ts",
"test": "playwright test",
"clean": "npx rimraf node_modules pnpm-lock.yaml",
"test:build": "pnpm install",
"test:assert": "pnpm test"
},
"dependencies": {
"@elysiajs/opentelemetry": "^1.4.0",
"@sentry/elysia": "latest || *",
"elysia": "^1.4.0"
},
"devDependencies": {
"@playwright/test": "~1.56.0",
"@sentry-internal/test-utils": "link:../../../test-utils",
"bun-types": "^1.2.9"
},
"volta": {
"extends": "../../package.json"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { getPlaywrightConfig } from '@sentry-internal/test-utils';

const config = getPlaywrightConfig({
startCommand: 'bun src/app.ts',
});

export default config;
142 changes: 142 additions & 0 deletions dev-packages/e2e-tests/test-applications/elysia-bun/src/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import * as Sentry from '@sentry/elysia';
import { Elysia } from 'elysia';

Sentry.init({
environment: 'qa', // dynamic sampling bias to keep transactions
dsn: process.env.E2E_TEST_DSN,
tunnel: `http://localhost:3031/`, // proxy server
tracesSampleRate: 1,
tracePropagationTargets: ['http://localhost:3030', '/external-allowed'],
});

const app = Sentry.withElysia(new Elysia());

// Simple success route
app.get('/test-success', () => ({ version: 'v1' }));

// Parameterized route
app.get('/test-param/:param', ({ params }) => ({ paramWas: params.param }));

// Multiple params
app.get('/test-multi-param/:param1/:param2', ({ params }) => ({
param1: params.param1,
param2: params.param2,
}));

// Route that throws an error (will be caught by onError)
app.get('/test-exception/:id', ({ params }) => {
throw new Error(`This is an exception with id ${params.id}`);
});

// Route with a custom span
app.get('/test-transaction', () => {
Sentry.startSpan({ name: 'test-span' }, () => {
Sentry.startSpan({ name: 'child-span' }, () => {});
});
return { status: 'ok' };
});

// Route with specific middleware via .guard or .use
app.group('/with-middleware', app =>
app
.onBeforeHandle(() => {
// This is a route-specific middleware
})
.get('/test', () => ({ middleware: true })),
);

// Error with specific status code
app.post('/test-post-error', () => {
throw new Error('Post error');
});

// Route that returns a non-500 error
app.get('/test-4xx', ({ set }) => {
set.status = 400;
return { error: 'Bad Request' };
});

// Error that reaches the error handler with status still set to 200 (unusual, should still be captured)
app.get('/test-error-with-200-status', ({ set }) => {
set.status = 200;
throw new Error('Error with 200 status');
});

// POST route that echoes body
app.post('/test-post', ({ body }) => ({ status: 'ok', body }));

// Route that returns inbound headers (for propagation tests)
app.get('/test-inbound-headers/:id', ({ params, request }) => {
const headers = Object.fromEntries(request.headers.entries());
return { headers, id: params.id };
});

// Outgoing fetch propagation
app.get('/test-outgoing-fetch/:id', async ({ params }) => {
const id = params.id;
const response = await fetch(`http://localhost:3030/test-inbound-headers/${id}`);
const data = await response.json();
return data;
});

// Outgoing fetch to external (allowed by tracePropagationTargets)
app.get('/test-outgoing-fetch-external-allowed', async () => {
const response = await fetch(`http://localhost:3040/external-allowed`);
const data = await response.json();
return data;
});

// Outgoing fetch to external (disallowed by tracePropagationTargets)
app.get('/test-outgoing-fetch-external-disallowed', async () => {
const response = await fetch(`http://localhost:3040/external-disallowed`);
const data = await response.json();
return data;
});

// Route that throws a string (not an Error object)
app.get('/test-string-error', () => {
// eslint-disable-next-line no-throw-literal
throw 'String error message';
});

// Route for concurrent isolation tests — returns scope data in response
app.get('/test-isolation/:userId', async ({ params }) => {
Sentry.setUser({ id: params.userId });
Sentry.setTag('user_id', params.userId);

// Simulate async work to increase overlap between concurrent requests
await new Promise(resolve => setTimeout(resolve, 200));

return {
userId: params.userId,
isolationScopeUserId: Sentry.getIsolationScope().getUser()?.id,
isolationScopeTag: Sentry.getIsolationScope().getScopeData().tags?.user_id,
};
});

// Flush route for waiting on events
app.get('/flush', async () => {
await Sentry.flush();
return { ok: true };
});

app.listen(3030, () => {
console.log('Elysia app listening on port 3030');
});

// Second app for external propagation tests
const app2 = new Elysia();

app2.get('/external-allowed', ({ request }) => {
const headers = Object.fromEntries(request.headers.entries());
return { headers, route: '/external-allowed' };
});

app2.get('/external-disallowed', ({ request }) => {
const headers = Object.fromEntries(request.headers.entries());
return { headers, route: '/external-disallowed' };
});

app2.listen(3040, () => {
console.log('External app listening on port 3040');
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { startEventProxyServer } from '@sentry-internal/test-utils';

startEventProxyServer({
port: 3031,
proxyServerName: 'elysia-bun',
});
Loading
Loading