Skip to content

Commit

Permalink
feat(keys/service.ts): enhance error message in KeyService for missin…
Browse files Browse the repository at this point in the history
…g ratelimit
  • Loading branch information
chronark committed Sep 24, 2024
1 parent 88bd752 commit 24bac4c
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 4 deletions.
15 changes: 11 additions & 4 deletions apps/api/src/pkg/keys/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ export class DisabledWorkspaceError extends BaseError<{ workspaceId: string }> {
export class MissingRatelimitError extends BaseError<{ name: string }> {
public readonly retry = false;
public readonly name = MissingRatelimitError.name;
constructor(name: string) {
constructor(ratelimitName: string, message: string) {
super({
message: `ratelimit "${name}" does not exist`,
message,
context: {
name,
name: ratelimitName,
},
});
}
Expand Down Expand Up @@ -504,7 +504,14 @@ export class KeyService {
continue;
}

return Err(new MissingRatelimitError(r.name));
let errorMessage = `ratelimit "${r.name}" was requested but does not exist for key "${data.key.id}"`;
if (data.identity) {
errorMessage += ` nor identity { id: ${data.identity.id}, externalId: ${data.identity.externalId}}`;
} else {
errorMessage += " and there is no identity connected";
}

return Err(new MissingRatelimitError(r.name, errorMessage));
}

const [pass, ratelimit] = await this.ratelimit(c, data.key, ratelimits);
Expand Down
94 changes: 94 additions & 0 deletions apps/api/src/routes/v1_keys_verifyKey.error.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { describe, expect, test } from "vitest";

import type { ErrorResponse } from "@/pkg/errors";
import { schema } from "@unkey/db";
import { newId } from "@unkey/id";
import { IntegrationHarness } from "src/pkg/testutil/integration-harness";

describe("with identity", () => {
describe("with ratelimits", () => {
describe("missing ratelimit", () => {
test("returns 400 and a useful error message", async (t) => {
const h = await IntegrationHarness.init(t);

const identity = {
id: newId("test"),
workspaceId: h.resources.userWorkspace.id,
externalId: newId("test"),
};
await h.db.primary.insert(schema.identities).values(identity);
await h.db.primary.insert(schema.ratelimits).values({
id: newId("test"),
workspaceId: h.resources.userWorkspace.id,
name: "existing-ratelimit",
identityId: identity.id,
limit: 100,
duration: 60_000,
});

const key = await h.createKey({ identityId: identity.id });

const res = await h.post<any, ErrorResponse>({
url: "/v1/keys.verifyKey",
headers: {
"Content-Type": "application/json",
},
body: {
key: key.key,
ratelimits: [
{
name: "does-not-exist",
},
],
},
});

expect(res.status).toEqual(400);
expect(res.body.error.message).toMatchInlineSnapshot(
`"ratelimit "does-not-exist" was requested but does not exist for key "test_2BC2hsZxB7P9WLR37L8K4jSwMugv" nor identity { id: test_2BC2hZebF4du9PYnijrmSryNP9xe, externalId: test_2BC2hZjbrfj1Zb1HgudRYbonQzpx}"`,
);
});
});
});
});

describe("without identity", () => {
describe("with ratelimits", () => {
describe("missing ratelimit", () => {
test("returns 400 and a useful error message", async (t) => {
const h = await IntegrationHarness.init(t);

const key = await h.createKey();

await h.db.primary.insert(schema.ratelimits).values({
id: newId("test"),
workspaceId: h.resources.userWorkspace.id,
name: "existing-ratelimit",
keyId: key.keyId,
limit: 100,
duration: 60_000,
});

const res = await h.post<any, ErrorResponse>({
url: "/v1/keys.verifyKey",
headers: {
"Content-Type": "application/json",
},
body: {
key: key.key,
ratelimits: [
{
name: "does-not-exist",
},
],
},
});

expect(res.status).toEqual(400);
expect(res.body.error.message).toMatchInlineSnapshot(
`"ratelimit "does-not-exist" was requested but does not exist for key "test_2BC2mdMQYnubdoAsBb2PD7MhooPs" and there is no identity connected"`,
);
});
});
});
});

0 comments on commit 24bac4c

Please sign in to comment.