Skip to content

test(node): Test vercelai errors are properly linked to parent span #17130

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import * as Sentry from '@sentry/node';
import { generateText, tool } from 'ai';
import { MockLanguageModelV1 } from 'ai/test';
import { z } from 'zod';

async function run() {
// Create a manual outer span (simulating the root span)
await Sentry.startSpan({ op: 'outer', name: 'outer span', description: 'outer span' }, async () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

description is an invalid field that does not exist anymore!

// It is expected that the error will bubble up naturally to the outer span
await generateText({
model: new MockLanguageModelV1({
doGenerate: async () => ({
rawCall: { rawPrompt: null, rawSettings: {} },
finishReason: 'stop',
usage: { promptTokens: 10, completionTokens: 20 },
text: 'First span here!',
toolCalls: [
{
toolCallType: 'function',
toolCallId: 'call-1',
toolName: 'calculateTool',
args: '{ "a": 1, "b": 2 }',
},
],
}),
}),
experimental_telemetry: {
functionId: 'Simple Agent',
recordInputs: true,
recordOutputs: true,
isEnabled: true,
},
tools: {
calculateTool: tool({
description: 'Calculate the result of a math problem. Returns a number.',
parameters: z.object({
a: z.number().describe('First number'),
b: z.number().describe('Second number'),
}),
type: 'function',
execute: async () => {
throw new Error('Not implemented');
},
}),
},
maxSteps: 2,
system: 'You help users with their math problems.',
prompt: 'What is 1 + 1?',
});
});
}

run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import * as Sentry from '@sentry/node';
import { generateText, tool } from 'ai';
import { MockLanguageModelV1 } from 'ai/test';
import express from 'express';
import { createServer } from 'http';
import { z } from 'zod';

async function run() {
const app = express();

app.get('/api/chat', async (req, res) => {
try {
await generateText({
model: new MockLanguageModelV1({
doGenerate: async () => ({
rawCall: { rawPrompt: null, rawSettings: {} },
finishReason: 'stop',
usage: { promptTokens: 10, completionTokens: 20 },
text: 'Processing your request...',
toolCalls: [
{
toolCallType: 'function',
toolCallId: 'call-1',
toolName: 'calculateTool',
args: '{ "a": 1, "b": 2 }',
},
],
}),
}),
experimental_telemetry: {
functionId: 'Chat Assistant',
recordInputs: true,
recordOutputs: true,
isEnabled: true,
},
tools: {
calculateTool: tool({
description: 'Calculate the result of a math problem. Returns a number.',
parameters: z.object({
a: z.number().describe('First number'),
b: z.number().describe('Second number'),
}),
type: 'function',
execute: async () => {
throw new Error('Calculation service unavailable');
},
}),
},
maxSteps: 2,
system: 'You are a helpful chat assistant.',
prompt: 'What is 1 + 1?',
});

res.json({ success: true });
} catch (error) {
res.status(500).json({ error: error.message });
}
});

Sentry.setupExpressErrorHandler(app);

const server = createServer(app);

// Start server and make request
server.listen(0, () => {
const port = server.address()?.port;
// eslint-disable-next-line no-console
console.log(JSON.stringify({ port }));

// Make the request that will trigger the error
fetch(`http://localhost:${port}/api/chat`)
.then(() => {
server.close();
})
.catch(() => {
server.close();
});
});
}

run();
Original file line number Diff line number Diff line change
Expand Up @@ -416,4 +416,94 @@
await createRunner().expect({ transaction: EXPECTED_TRANSACTION_DEFAULT_PII_TRUE }).start().completed();
});
});

createEsmAndCjsTests(__dirname, 'scenario-error.mjs', 'instrument-with-pii.mjs', (createRunner, test) => {
test('Vercel AI errors should inherit parent trace context from manually created outer span', async () => {
let capturedTransaction: any;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

l: let's avoid any here and use the Event type :)

let capturedEvent: any;

const runner = createRunner()
.expect({
transaction: (transaction: any) => {
capturedTransaction = transaction;
expect(transaction.transaction).toBe('outer span');
},
})
.expect({
event: (event: any) => {
capturedEvent = event;

expect(event).toMatchObject({
exception: {
values: expect.arrayContaining([
expect.objectContaining({
type: 'AI_ToolExecutionError',
value: 'Error executing tool calculateTool: Not implemented',
}),
]),
},
});
},
})
.start();

await runner.completed();

const transactionTraceId = capturedTransaction?.contexts?.trace?.trace_id;
const errorTraceId = capturedEvent?.contexts?.trace?.trace_id;

expect(transactionTraceId).toBeDefined();
expect(errorTraceId).toBeDefined();
expect(transactionTraceId).toMatch(/^[a-f0-9]{32}$/);
expect(errorTraceId).toMatch(/^[a-f0-9]{32}$/);

expect(errorTraceId).toBe(transactionTraceId);

Check failure on line 460 in dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts

View workflow job for this annotation

GitHub Actions / Node (20) Integration Tests

suites/tracing/vercelai/test.ts > Vercel AI integration > cjs > Vercel AI errors should inherit parent trace context from manually created outer span

AssertionError: expected '63ba09230d08496abb2007561aa320d7' to be '63fcae3432d642246ee7727fccf43121' // Object.is equality Expected: "63fcae3432d642246ee7727fccf43121" Received: "63ba09230d08496abb2007561aa320d7" ❯ suites/tracing/vercelai/test.ts:460:28

Check failure on line 460 in dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts

View workflow job for this annotation

GitHub Actions / Node (20) Integration Tests

suites/tracing/vercelai/test.ts > Vercel AI integration > esm > Vercel AI errors should inherit parent trace context from manually created outer span

AssertionError: expected 'e66dd6337a4e42dc9fbb29d7b43626d5' to be '52b14787a6231dc722f61bac9f274e37' // Object.is equality Expected: "52b14787a6231dc722f61bac9f274e37" Received: "e66dd6337a4e42dc9fbb29d7b43626d5" ❯ suites/tracing/vercelai/test.ts:460:28

Check failure on line 460 in dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts

View workflow job for this annotation

GitHub Actions / Node (18) Integration Tests

suites/tracing/vercelai/test.ts > Vercel AI integration > cjs > Vercel AI errors should inherit parent trace context from manually created outer span

AssertionError: expected '95de20ceaef04883bd496865636de7df' to be '4f1c9a3cd5ed6bcde3d79cf2f8344b9c' // Object.is equality Expected: "4f1c9a3cd5ed6bcde3d79cf2f8344b9c" Received: "95de20ceaef04883bd496865636de7df" ❯ suites/tracing/vercelai/test.ts:460:28

Check failure on line 460 in dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts

View workflow job for this annotation

GitHub Actions / Node (18) Integration Tests

suites/tracing/vercelai/test.ts > Vercel AI integration > esm > Vercel AI errors should inherit parent trace context from manually created outer span

AssertionError: expected '7f45716d720e4fc8a555acac661c116c' to be '0a432c9599044bfe2d65377c707efd88' // Object.is equality Expected: "0a432c9599044bfe2d65377c707efd88" Received: "7f45716d720e4fc8a555acac661c116c" ❯ suites/tracing/vercelai/test.ts:460:28

Check failure on line 460 in dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts

View workflow job for this annotation

GitHub Actions / Node (24) (TS 3.8) Integration Tests

suites/tracing/vercelai/test.ts > Vercel AI integration > cjs > Vercel AI errors should inherit parent trace context from manually created outer span

AssertionError: expected 'ab38eb33c25843efb23d821105a68965' to be 'a6ce1d374689f3b6d9ac1273639981f9' // Object.is equality Expected: "a6ce1d374689f3b6d9ac1273639981f9" Received: "ab38eb33c25843efb23d821105a68965" ❯ suites/tracing/vercelai/test.ts:460:28

Check failure on line 460 in dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts

View workflow job for this annotation

GitHub Actions / Node (24) (TS 3.8) Integration Tests

suites/tracing/vercelai/test.ts > Vercel AI integration > esm > Vercel AI errors should inherit parent trace context from manually created outer span

AssertionError: expected '7e5e8f77bfb54be8bae82fa0e656172f' to be '7db3d812c890c8006dbdb1b1af5c2c14' // Object.is equality Expected: "7db3d812c890c8006dbdb1b1af5c2c14" Received: "7e5e8f77bfb54be8bae82fa0e656172f" ❯ suites/tracing/vercelai/test.ts:460:28

Check failure on line 460 in dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts

View workflow job for this annotation

GitHub Actions / Node (22) Integration Tests

suites/tracing/vercelai/test.ts > Vercel AI integration > cjs > Vercel AI errors should inherit parent trace context from manually created outer span

AssertionError: expected '6f7665dc900745fd9719c7dcace3229c' to be '3513bb0d6b222ba8f203e1585b282984' // Object.is equality Expected: "3513bb0d6b222ba8f203e1585b282984" Received: "6f7665dc900745fd9719c7dcace3229c" ❯ suites/tracing/vercelai/test.ts:460:28

Check failure on line 460 in dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts

View workflow job for this annotation

GitHub Actions / Node (22) Integration Tests

suites/tracing/vercelai/test.ts > Vercel AI integration > esm > Vercel AI errors should inherit parent trace context from manually created outer span

AssertionError: expected 'e0353a694e3b4fe9a29324b097e0f506' to be 'dc4f58aed7cae98789b6cf04fd3be346' // Object.is equality Expected: "dc4f58aed7cae98789b6cf04fd3be346" Received: "e0353a694e3b4fe9a29324b097e0f506" ❯ suites/tracing/vercelai/test.ts:460:28

Check failure on line 460 in dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts

View workflow job for this annotation

GitHub Actions / Node (24) Integration Tests

suites/tracing/vercelai/test.ts > Vercel AI integration > cjs > Vercel AI errors should inherit parent trace context from manually created outer span

AssertionError: expected 'cafcb91e9a9b4f09a8473b70645b6468' to be '34a32d2fe988a13f6dd1636114e80d21' // Object.is equality Expected: "34a32d2fe988a13f6dd1636114e80d21" Received: "cafcb91e9a9b4f09a8473b70645b6468" ❯ suites/tracing/vercelai/test.ts:460:28

Check failure on line 460 in dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts

View workflow job for this annotation

GitHub Actions / Node (24) Integration Tests

suites/tracing/vercelai/test.ts > Vercel AI integration > esm > Vercel AI errors should inherit parent trace context from manually created outer span

AssertionError: expected '6f5783f5465a439993ac6547d47f8545' to be 'a89a4f7877cef3b542460b3ab4f2ad02' // Object.is equality Expected: "a89a4f7877cef3b542460b3ab4f2ad02" Received: "6f5783f5465a439993ac6547d47f8545" ❯ suites/tracing/vercelai/test.ts:460:28
});
});

createEsmAndCjsTests(__dirname, 'scenario-express-error.mjs', 'instrument-with-pii.mjs', (createRunner, test) => {
test('Vercel AI errors should inherit parent trace context from server HTTP request', async () => {

Check failure on line 465 in dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts

View workflow job for this annotation

GitHub Actions / Node (20) Integration Tests

suites/tracing/vercelai/test.ts > Vercel AI integration > cjs > Vercel AI errors should inherit parent trace context from server HTTP request

Error: Test timed out in 15000ms. If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout". ❯ suites/tracing/vercelai/test.ts:465:5 ❯ utils/runner.ts:219:5

Check failure on line 465 in dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts

View workflow job for this annotation

GitHub Actions / Node (20) Integration Tests

suites/tracing/vercelai/test.ts > Vercel AI integration > esm > Vercel AI errors should inherit parent trace context from server HTTP request

Error: Test timed out in 15000ms. If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout". ❯ suites/tracing/vercelai/test.ts:465:5 ❯ utils/runner.ts:195:5

Check failure on line 465 in dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts

View workflow job for this annotation

GitHub Actions / Node (18) Integration Tests

suites/tracing/vercelai/test.ts > Vercel AI integration > cjs > Vercel AI errors should inherit parent trace context from server HTTP request

Error: Test timed out in 15000ms. If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout". ❯ suites/tracing/vercelai/test.ts:465:5 ❯ utils/runner.ts:219:5

Check failure on line 465 in dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts

View workflow job for this annotation

GitHub Actions / Node (18) Integration Tests

suites/tracing/vercelai/test.ts > Vercel AI integration > esm > Vercel AI errors should inherit parent trace context from server HTTP request

Error: Test timed out in 15000ms. If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout". ❯ suites/tracing/vercelai/test.ts:465:5 ❯ utils/runner.ts:195:5

Check failure on line 465 in dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts

View workflow job for this annotation

GitHub Actions / Node (24) (TS 3.8) Integration Tests

suites/tracing/vercelai/test.ts > Vercel AI integration > cjs > Vercel AI errors should inherit parent trace context from server HTTP request

Error: Test timed out in 15000ms. If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout". ❯ suites/tracing/vercelai/test.ts:465:5 ❯ utils/runner.ts:219:5

Check failure on line 465 in dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts

View workflow job for this annotation

GitHub Actions / Node (24) (TS 3.8) Integration Tests

suites/tracing/vercelai/test.ts > Vercel AI integration > esm > Vercel AI errors should inherit parent trace context from server HTTP request

Error: Test timed out in 15000ms. If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout". ❯ suites/tracing/vercelai/test.ts:465:5 ❯ utils/runner.ts:195:5

Check failure on line 465 in dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts

View workflow job for this annotation

GitHub Actions / Node (22) Integration Tests

suites/tracing/vercelai/test.ts > Vercel AI integration > cjs > Vercel AI errors should inherit parent trace context from server HTTP request

Error: Test timed out in 15000ms. If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout". ❯ suites/tracing/vercelai/test.ts:465:5 ❯ utils/runner.ts:219:5

Check failure on line 465 in dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts

View workflow job for this annotation

GitHub Actions / Node (22) Integration Tests

suites/tracing/vercelai/test.ts > Vercel AI integration > esm > Vercel AI errors should inherit parent trace context from server HTTP request

Error: Test timed out in 15000ms. If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout". ❯ suites/tracing/vercelai/test.ts:465:5 ❯ utils/runner.ts:195:5

Check failure on line 465 in dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts

View workflow job for this annotation

GitHub Actions / Node (24) Integration Tests

suites/tracing/vercelai/test.ts > Vercel AI integration > cjs > Vercel AI errors should inherit parent trace context from server HTTP request

Error: Test timed out in 15000ms. If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout". ❯ suites/tracing/vercelai/test.ts:465:5 ❯ utils/runner.ts:219:5

Check failure on line 465 in dev-packages/node-integration-tests/suites/tracing/vercelai/test.ts

View workflow job for this annotation

GitHub Actions / Node (24) Integration Tests

suites/tracing/vercelai/test.ts > Vercel AI integration > esm > Vercel AI errors should inherit parent trace context from server HTTP request

Error: Test timed out in 15000ms. If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout". ❯ suites/tracing/vercelai/test.ts:465:5 ❯ utils/runner.ts:195:5
let capturedTransaction: any;
let capturedEvent: any;

const runner = createRunner()
.withMockSentryServer()
.expect({
transaction: (transaction: any) => {
capturedTransaction = transaction;
// Express creates a transaction like "GET /api/chat"
expect(transaction.transaction).toBe('GET /api/chat');
},
})
.expect({
event: (event: any) => {
capturedEvent = event;

expect(event).toMatchObject({
exception: {
values: expect.arrayContaining([
expect.objectContaining({
type: 'AI_ToolExecutionError',
value: 'Error executing tool calculateTool: Calculation service unavailable',
}),
]),
},
});
},
})
.start();

await runner.completed();

const transactionTraceId = capturedTransaction?.contexts?.trace?.trace_id;
const errorTraceId = capturedEvent?.contexts?.trace?.trace_id;

expect(transactionTraceId).toBeDefined();
expect(errorTraceId).toBeDefined();
expect(transactionTraceId).toMatch(/^[a-f0-9]{32}$/);
expect(errorTraceId).toMatch(/^[a-f0-9]{32}$/);

expect(errorTraceId).toBe(transactionTraceId);
});
});
});
Loading