115 lines
2.8 KiB
TypeScript
115 lines
2.8 KiB
TypeScript
import { ErrCode, RecaseError } from "@autumn/shared";
|
|
import { expect, test } from "bun:test";
|
|
import { APIError } from "better-auth";
|
|
import { Hono } from "hono";
|
|
import { errorMiddleware } from "@/honoMiddlewares/errorMiddleware.js";
|
|
import type { HonoEnv } from "@/honoUtils/HonoEnv.js";
|
|
|
|
test("error middleware returns RecaseError status before request context exists", async () => {
|
|
const app = new Hono<HonoEnv>();
|
|
|
|
app.get("/api/auth/organization/list", () => {
|
|
throw new RecaseError({
|
|
message: "Unauthorized - no session found",
|
|
code: ErrCode.NoAuthHeader,
|
|
statusCode: 401,
|
|
});
|
|
});
|
|
app.onError(errorMiddleware);
|
|
|
|
const response = await app.fetch(
|
|
new Request("https://autumn-api.bowong.cc/api/auth/organization/list"),
|
|
);
|
|
|
|
expect(response.status).toBe(401);
|
|
await expect(response.json()).resolves.toMatchObject({
|
|
message: "Unauthorized - no session found",
|
|
code: ErrCode.NoAuthHeader,
|
|
});
|
|
});
|
|
|
|
test("error middleware maps Stripe-shaped errors to a 400", async () => {
|
|
const app = new Hono<HonoEnv>();
|
|
const consoleErrors: unknown[][] = [];
|
|
const originalConsoleError = console.error;
|
|
console.error = (...args: unknown[]) => {
|
|
consoleErrors.push(args);
|
|
};
|
|
|
|
app.use("*", async (c, next) => {
|
|
c.set("ctx", {
|
|
env: "sandbox",
|
|
logger: {
|
|
error: () => {},
|
|
warn: () => {},
|
|
},
|
|
} as never);
|
|
await next();
|
|
});
|
|
|
|
app.post("/v1/rewards", () => {
|
|
const error = new Error("No such product: prod_missing") as Error & {
|
|
type: string;
|
|
statusCode: number;
|
|
code: string;
|
|
};
|
|
error.type = "StripeInvalidRequestError";
|
|
error.statusCode = 400;
|
|
error.code = "resource_missing";
|
|
throw error;
|
|
});
|
|
app.onError(errorMiddleware);
|
|
|
|
try {
|
|
const response = await app.fetch(
|
|
new Request("https://autumn-api.bowong.cc/v1/rewards", {
|
|
method: "POST",
|
|
}),
|
|
);
|
|
|
|
expect(response.status).toBe(400);
|
|
await expect(response.json()).resolves.toMatchObject({
|
|
message: "(Stripe Error) No such product: prod_missing",
|
|
code: ErrCode.StripeError,
|
|
env: "sandbox",
|
|
});
|
|
expect(consoleErrors).toEqual([]);
|
|
} finally {
|
|
console.error = originalConsoleError;
|
|
}
|
|
});
|
|
|
|
test("error middleware preserves Better Auth unauthorized errors", async () => {
|
|
const app = new Hono<HonoEnv>();
|
|
|
|
app.use("*", async (c, next) => {
|
|
c.set("ctx", {
|
|
env: "sandbox",
|
|
logger: {
|
|
error: () => {},
|
|
warn: () => {},
|
|
},
|
|
} as never);
|
|
await next();
|
|
});
|
|
|
|
app.get("/query/event_names/list", () => {
|
|
throw APIError.from("UNAUTHORIZED", {
|
|
message: "Unauthorized",
|
|
code: "UNAUTHORIZED",
|
|
});
|
|
});
|
|
app.onError(errorMiddleware);
|
|
|
|
const response = await app.fetch(
|
|
new Request("https://autumn-api.bowong.cc/query/event_names/list"),
|
|
);
|
|
|
|
expect(response.status).toBe(401);
|
|
await expect(response.json()).resolves.toMatchObject({
|
|
message: "Unauthorized",
|
|
code: ErrCode.NoAuthHeader,
|
|
env: "sandbox",
|
|
});
|
|
});
|