Skip to content

Commit

Permalink
feat: support expired and not-found ref API errors
Browse files Browse the repository at this point in the history
  • Loading branch information
angeloashmore committed Oct 2, 2023
1 parent 1e22703 commit 95aa906
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 5 deletions.
21 changes: 17 additions & 4 deletions src/createClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import { ForbiddenError } from "./errors/ForbiddenError";
import { NotFoundError } from "./errors/NotFoundError";
import { ParsingError } from "./errors/ParsingError";
import { PrismicError } from "./errors/PrismicError";
import { RefExpiredError } from "./errors/RefExpiredError";
import { RefNotFoundError } from "./errors/RefNotFoundError";

import { LinkResolverFunction, asLink } from "./helpers/asLink";

Expand Down Expand Up @@ -1900,22 +1902,33 @@ export class Client<TDocuments extends PrismicDocument = PrismicDocument> {
// - Incorrect access token for query endpoint
case 403: {
throw new ForbiddenError(
"error" in res.json ? res.json.error : res.json.message,
res.json.error || res.json.message,
url,
res.json,
);
}

// Not Found (this response has an empty body)
// - Incorrect repository name
// Not Found
// - Incorrect repository name (this response has an empty body)
// - Ref does not exist
case 404: {
if (res.json && res.json.type === "api_notfound_error") {
throw new RefNotFoundError(res.json.message, url, res.json);
}

throw new NotFoundError(
`Prismic repository not found. Check that "${this.endpoint}" is pointing to the correct repository.`,
url,
undefined,
undefined, // res.json is empty
);
}

// Gone
// - Ref is expired
case 410: {
throw new RefExpiredError(res.json.message, url, res.json);
}

// Too Many Requests
// - Exceeded the maximum number of requests per second
case 429: {
Expand Down
8 changes: 8 additions & 0 deletions src/errors/RefExpiredError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { PrismicError } from "./PrismicError";

type RefExpiredErrorAPIResponse = {
type: "api_validation_error";
message: string;
};

export class RefExpiredError extends PrismicError<RefExpiredErrorAPIResponse> {}
8 changes: 8 additions & 0 deletions src/errors/RefNotFoundError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { PrismicError } from "./PrismicError";

type RefNotFoundErrorAPIResponse = {
type: "api_notfound_error";
message: string;
};

export class RefNotFoundError extends PrismicError<RefNotFoundErrorAPIResponse> {}
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ export type { HTMLRichTextSerializer } from "./helpers/asHTML";
export { PrismicError } from "./errors/PrismicError";
export { ForbiddenError } from "./errors/ForbiddenError";
export { NotFoundError } from "./errors/NotFoundError";
export { RefNotFoundError } from "./errors/RefNotFoundError";
export { RefExpiredError } from "./errors/RefExpiredError";
export { ParsingError } from "./errors/ParsingError";

//=============================================================================
Expand Down
56 changes: 55 additions & 1 deletion test/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,7 @@ it("throws PrismicError if response is not 200, 400, 401, 403, or 404", async (c
const client = createTestClient();

const queryEndpoint = new URL(
"documents/search",
"./documents/search",
`${client.endpoint}/`,
).toString();

Expand Down Expand Up @@ -684,6 +684,60 @@ it("throws NotFoundError if repository does not exist", async (ctx) => {
await expect(() => client.get()).rejects.toThrowError(prismic.NotFoundError);
});

it("throws RefNotFoundError if ref does not exist", async (ctx) => {
const queryResponse = {
type: "api_notfound_error",
message: "message",
};

mockPrismicRestAPIV2({ ctx });

const client = createTestClient();

const queryEndpoint = new URL(
"./documents/search",
`${client.endpoint}/`,
).toString();

ctx.server.use(
msw.rest.get(queryEndpoint, (_req, res, ctx) => {
return res(ctx.status(404), ctx.json(queryResponse));
}),
);

await expect(() => client.get()).rejects.toThrowError(queryResponse.message);
await expect(() => client.get()).rejects.toThrowError(
prismic.RefNotFoundError,
);
});

it("throws RefExpiredError if ref is expired", async (ctx) => {
const queryResponse = {
type: "api_validation_error",
message: "message",
};

mockPrismicRestAPIV2({ ctx });

const client = createTestClient();

const queryEndpoint = new URL(
"./documents/search",
`${client.endpoint}/`,
).toString();

ctx.server.use(
msw.rest.get(queryEndpoint, (_req, res, ctx) => {
return res(ctx.status(410), ctx.json(queryResponse));
}),
);

await expect(() => client.get()).rejects.toThrowError(queryResponse.message);
await expect(() => client.get()).rejects.toThrowError(
prismic.RefExpiredError,
);
});

it("retries after `retry-after` milliseconds if response code is 429", async (ctx) => {
const retryAfter = 200; // ms
/**
Expand Down

0 comments on commit 95aa906

Please sign in to comment.