Skip to content
Draft
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,25 @@
const Sentry = require('@sentry/node');
const { loggingTransport } = require('@sentry-internal/node-integration-tests');

Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
release: '1.0',
tracesSampleRate: 1.0,
transport: loggingTransport,
integrations: [
Sentry.postgresJsIntegration({
requestHook: (span, sanitizedSqlQuery, connectionContext) => {
// Add custom attributes to demonstrate requestHook functionality
span.setAttribute('custom.requestHook', 'called');

// Set context information as extras for test validation
Sentry.setExtra('requestHookCalled', {
sanitizedQuery: sanitizedSqlQuery,
database: connectionContext?.database,
host: connectionContext?.host,
port: connectionContext?.port,
});
},
}),
],
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import * as Sentry from '@sentry/node';
import { loggingTransport } from '@sentry-internal/node-integration-tests';

Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
release: '1.0',
tracesSampleRate: 1.0,
transport: loggingTransport,
integrations: [
Sentry.postgresJsIntegration({
requestHook: (span, sanitizedSqlQuery, connectionContext) => {
// Add custom attributes to demonstrate requestHook functionality
span.setAttribute('custom.requestHook', 'called');

// Set context information as extras for test validation
Sentry.setExtra('requestHookCalled', {
sanitizedQuery: sanitizedSqlQuery,
database: connectionContext?.database,
host: connectionContext?.host,
port: connectionContext?.port,
});
},
}),
],
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const Sentry = require('@sentry/node');
const { loggingTransport } = require('@sentry-internal/node-integration-tests');

Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
release: '1.0',
tracesSampleRate: 1.0,
transport: loggingTransport,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import * as Sentry from '@sentry/node';
import { loggingTransport } from '@sentry-internal/node-integration-tests';

Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
release: '1.0',
tracesSampleRate: 1.0,
transport: loggingTransport,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
const { loggingTransport } = require('@sentry-internal/node-integration-tests');
const Sentry = require('@sentry/node');

Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
release: '1.0',
tracesSampleRate: 1.0,
transport: loggingTransport,
});

// Stop the process from exiting before the transaction is sent
setInterval(() => {}, 1000);

const postgres = require('postgres');

const sql = postgres({ port: 5444, user: 'test', password: 'test', database: 'test_db' });

async function run() {
await Sentry.startSpan(
{
name: 'Test Transaction',
op: 'transaction',
},
async () => {
try {
await sql`
CREATE TABLE "User" ("id" SERIAL NOT NULL,"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,"email" TEXT NOT NULL,"name" TEXT,CONSTRAINT "User_pkey" PRIMARY KEY ("id"));
`;

await sql`
INSERT INTO "User" ("email", "name") VALUES ('Foo', 'bar@baz.com');
`;

await sql`
SELECT * FROM "User" WHERE "email" = 'bar@baz.com';
`;

await sql`
DROP TABLE "User";
`;
} finally {
await sql.end();
}
},
);
}

// eslint-disable-next-line @typescript-eslint/no-floating-promises
run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as Sentry from '@sentry/node';
import postgres from 'postgres';

// Stop the process from exiting before the transaction is sent
setInterval(() => {}, 1000);

const sql = postgres({ port: 5444, user: 'test', password: 'test', database: 'test_db' });

async function run() {
await Sentry.startSpan(
{
name: 'Test Transaction',
op: 'transaction',
},
async () => {
try {
await sql`
CREATE TABLE "User" ("id" SERIAL NOT NULL,"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,"email" TEXT NOT NULL,"name" TEXT,CONSTRAINT "User_pkey" PRIMARY KEY ("id"));
`;

await sql`
INSERT INTO "User" ("email", "name") VALUES ('Foo', 'bar@baz.com');
`;

await sql`
SELECT * FROM "User" WHERE "email" = 'bar@baz.com';
`;

await sql`
DROP TABLE "User";
`;
} finally {
await sql.end();
}
},
);
}

// eslint-disable-next-line @typescript-eslint/no-floating-promises
run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const { loggingTransport } = require('@sentry-internal/node-integration-tests');
const Sentry = require('@sentry/node');

Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
release: '1.0',
tracesSampleRate: 1.0,
transport: loggingTransport,
});

// Import postgres AFTER Sentry.init() so instrumentation is set up
const postgres = require('postgres');

// Stop the process from exiting before the transaction is sent
setInterval(() => {}, 1000);

// Test with plain object options
const sql = postgres({ port: 5444, user: 'test', password: 'test', database: 'test_db' });

async function run() {
await Sentry.startSpan(
{
name: 'Test Transaction',
op: 'transaction',
},
async () => {
try {
// Test sql.unsafe() - this was not being instrumented before the fix
await sql.unsafe('CREATE TABLE "User" ("id" SERIAL NOT NULL, "email" TEXT NOT NULL, PRIMARY KEY ("id"))');

await sql.unsafe('INSERT INTO "User" ("email") VALUES ($1)', ['test@example.com']);

await sql.unsafe('SELECT * FROM "User" WHERE "email" = $1', ['test@example.com']);

await sql.unsafe('DROP TABLE "User"');

// This will be captured as an error as the table no longer exists
await sql.unsafe('SELECT * FROM "User"');
} finally {
await sql.end();
}
},
);
}

run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
const { loggingTransport } = require('@sentry-internal/node-integration-tests');
const Sentry = require('@sentry/node');

Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
release: '1.0',
tracesSampleRate: 1.0,
transport: loggingTransport,
});

// Import postgres AFTER Sentry.init() so instrumentation is set up
const postgres = require('postgres');

// Stop the process from exiting before the transaction is sent
setInterval(() => {}, 1000);

// Test URL-based initialization - this is the common pattern that was causing the regression
const sql = postgres('postgres://test:test@localhost:5444/test_db');

async function run() {
await Sentry.startSpan(
{
name: 'Test Transaction',
op: 'transaction',
},
async () => {
try {
await sql`
CREATE TABLE "User" ("id" SERIAL NOT NULL,"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,"email" TEXT NOT NULL,"name" TEXT,CONSTRAINT "User_pkey" PRIMARY KEY ("id"));
`;

await sql`
INSERT INTO "User" ("email", "name") VALUES ('Foo', 'bar@baz.com');
`;

await sql`
UPDATE "User" SET "name" = 'Foo' WHERE "email" = 'bar@baz.com';
`;

await sql`
SELECT * FROM "User" WHERE "email" = 'bar@baz.com';
`;

await sql`SELECT * from generate_series(1,1000) as x `.cursor(10, async rows => {
await Promise.all(rows);
});

await sql`
DROP TABLE "User";
`;

// This will be captured as an error as the table no longer exists
await sql`
SELECT * FROM "User" WHERE "email" = 'foo@baz.com';
`;
} finally {
await sql.end();
}
},
);
}

run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import * as Sentry from '@sentry/node';
import postgres from 'postgres';

// Stop the process from exiting before the transaction is sent
setInterval(() => {}, 1000);

// Test URL-based initialization - this is the common pattern that was causing the regression
const sql = postgres('postgres://test:test@localhost:5444/test_db');

async function run() {
await Sentry.startSpan(
{
name: 'Test Transaction',
op: 'transaction',
},
async () => {
try {
await sql`
CREATE TABLE "User" ("id" SERIAL NOT NULL,"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,"email" TEXT NOT NULL,"name" TEXT,CONSTRAINT "User_pkey" PRIMARY KEY ("id"));
`;

await sql`
INSERT INTO "User" ("email", "name") VALUES ('Foo', 'bar@baz.com');
`;

await sql`
UPDATE "User" SET "name" = 'Foo' WHERE "email" = 'bar@baz.com';
`;

await sql`
SELECT * FROM "User" WHERE "email" = 'bar@baz.com';
`;

// Test parameterized queries
await sql`
SELECT * FROM "User" WHERE "email" = ${'bar@baz.com'} AND "name" = ${'Foo'};
`;

// Test DELETE operation
await sql`
DELETE FROM "User" WHERE "email" = 'bar@baz.com';
`;

// Test INSERT with RETURNING
await sql`
INSERT INTO "User" ("email", "name") VALUES ('test@example.com', 'Test User') RETURNING *;
`;

// Test cursor-based queries
await sql`SELECT * from generate_series(1,1000) as x `.cursor(10, async rows => {
await Promise.all(rows);
});

// Test multiple rows at once
await sql`
SELECT * FROM "User" LIMIT 10;
`;

await sql`
DROP TABLE "User";
`;

// This will be captured as an error as the table no longer exists
await sql`
SELECT * FROM "User" WHERE "email" = 'foo@baz.com';
`;
} finally {
await sql.end();
}
},
);
}

// eslint-disable-next-line @typescript-eslint/no-floating-promises
run();
Loading
Loading