fix: stop reporting handled payment required errors (#70)

* fix: stop reporting handled payment required errors

* save
This commit is contained in:
Ben Senescu 2026-04-04 18:23:49 -04:00 committed by Ben Senescu
parent d773105e8d
commit f75a1d4156
4 changed files with 35 additions and 20 deletions

View File

@ -1,6 +1,7 @@
import { Link, rootRouteId, useMatch, useRouter } from "@tanstack/react-router";
import type { ErrorComponentProps } from "@tanstack/react-router";
import * as React from "react";
import { shouldCaptureAppErrorCode } from "@/shared/error-codes";
import {
getErrorCode,
getStandardErrorMessage,
@ -9,16 +10,6 @@ import { AuthConfigErrorCard } from "@/client/components/AuthConfigErrorCard";
import { captureClientError } from "@/client/lib/posthog";
import { UnauthenticatedErrorCard } from "@/client/components/UnauthenticatedErrorCard";
function shouldCaptureBoundaryError(
errorCode: ReturnType<typeof getErrorCode>,
) {
return (
errorCode !== "UNAUTHENTICATED" &&
errorCode !== "NOT_FOUND" &&
errorCode !== "VALIDATION_ERROR"
);
}
export function DefaultCatchBoundary({ error }: ErrorComponentProps) {
const router = useRouter();
const isRoot = useMatch({
@ -34,7 +25,7 @@ export function DefaultCatchBoundary({ error }: ErrorComponentProps) {
const errorCode = getErrorCode(error);
React.useEffect(() => {
if (!shouldCaptureBoundaryError(errorCode)) {
if (!shouldCaptureAppErrorCode(errorCode)) {
return;
}

View File

@ -1,17 +1,10 @@
import { createMiddleware } from "@tanstack/react-start";
import { getRequest } from "@tanstack/react-start/server";
import { waitUntil } from "cloudflare:workers";
import { shouldCaptureAppErrorCode } from "@/shared/error-codes";
import { asAppError, toClientError } from "@/server/lib/errors";
import { captureServerError } from "@/server/lib/posthog";
function shouldCaptureServerError(code: string | null | undefined) {
return (
code !== "UNAUTHENTICATED" &&
code !== "NOT_FOUND" &&
code !== "VALIDATION_ERROR"
);
}
export const errorHandlingMiddleware = createMiddleware({
type: "function",
}).server(async (c) => {
@ -26,7 +19,7 @@ export const errorHandlingMiddleware = createMiddleware({
const appError = asAppError(error);
if (shouldCaptureServerError(appError?.code)) {
if (shouldCaptureAppErrorCode(appError?.code)) {
const request = getRequest();
const url = new URL(request.url);

View File

@ -0,0 +1,18 @@
import { describe, expect, it } from "vitest";
import { shouldCaptureAppErrorCode } from "@/shared/error-codes";
describe("shouldCaptureAppErrorCode", () => {
it.each([
"UNAUTHENTICATED",
"NOT_FOUND",
"PAYMENT_REQUIRED",
"VALIDATION_ERROR",
] as const)("skips expected %s errors", (code) => {
expect(shouldCaptureAppErrorCode(code)).toBe(false);
});
it("captures unexpected errors and unknown failures", () => {
expect(shouldCaptureAppErrorCode("INTERNAL_ERROR")).toBe(true);
expect(shouldCaptureAppErrorCode(undefined)).toBe(true);
});
});

View File

@ -20,6 +20,19 @@ export const errorCodeSchema = z.enum(ERROR_CODES);
export type ErrorCode = z.infer<typeof errorCodeSchema>;
const NON_REPORTABLE_ERROR_CODES = new Set<ErrorCode>([
"UNAUTHENTICATED",
"NOT_FOUND",
"PAYMENT_REQUIRED",
"VALIDATION_ERROR",
]);
export function isErrorCode(value: string): value is ErrorCode {
return errorCodeSchema.safeParse(value).success;
}
export function shouldCaptureAppErrorCode(
code: ErrorCode | null | undefined,
): boolean {
return code == null || !NON_REPORTABLE_ERROR_CODES.has(code);
}