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
5 changes: 5 additions & 0 deletions .changeset/gold-donuts-leave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"wrangler": patch
---

fix: prevent reporting SQLite error from `wrangler d1 execute` to Sentry
22 changes: 21 additions & 1 deletion packages/wrangler/src/__tests__/d1/execute.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import fs from "node:fs";
import { join } from "path";
import { join } from "node:path";
import { http, HttpResponse } from "msw";
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import { UserError } from "../../errors";
import { mockAccountId, mockApiToken } from "../helpers/mock-account-id";
import { mockConsoleMethods } from "../helpers/mock-console";
import { useMockIsTTY } from "../helpers/mock-istty";
Expand Down Expand Up @@ -185,6 +187,24 @@ describe("execute", () => {
expect(std.out).not.toContain("⛅️ wrangler x.x.x");
});

it("should treat SQLite constraint errors as UserErrors", async () => {
// First create a table with a foreign key constraint
const setupSQL = `
CREATE TABLE users (id INTEGER PRIMARY KEY);
CREATE TABLE posts (id INTEGER PRIMARY KEY, user_id INTEGER, FOREIGN KEY(user_id) REFERENCES users(id));
`;
fs.writeFileSync("setup.sql", setupSQL);
await runWrangler("d1 execute db --file setup.sql --local");

// Now try to violate the foreign key constraint
const violationSQL = `INSERT INTO posts (id, user_id) VALUES (1, 999);`;
fs.writeFileSync("violation.sql", violationSQL);

await expect(
runWrangler("d1 execute db --file violation.sql --local")
).rejects.toThrow(UserError);
});

describe("duration formatting", () => {
mockAccountId({ accountId: "some-account-id" });
mockApiToken();
Expand Down
32 changes: 31 additions & 1 deletion packages/wrangler/src/d1/execute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,30 @@ export type QueryResult = {
query?: string;
};

// Common SQLite Codes
// See https://www.sqlite.org/rescode.html#constraint
const SQLITE_RESULT_CODES = [
"SQLITE_ERROR",
"SQLITE_CONSTRAINT",
"SQLITE_MISMATCH",
];

function isSqliteUserError(error: unknown): error is Error {
if (!(error instanceof Error)) {
return false;
}

const message = error.message.toUpperCase();

for (const code of SQLITE_RESULT_CODES) {
if (message.includes(code)) {
return true;
}
}

return false;
}

export function Options(yargs: CommonYargsArgv) {
return options
.Database(yargs)
Expand Down Expand Up @@ -305,7 +329,13 @@ async function executeLocally({
try {
results = await db.batch(queries.map((query) => db.prepare(query)));
} catch (e: unknown) {
throw (e as { cause?: unknown })?.cause ?? e;
const cause = (e as { cause?: unknown })?.cause ?? e;

if (isSqliteUserError(cause)) {
throw new UserError(cause.message);
}

throw cause;
} finally {
await mf.dispose();
}
Expand Down
Loading