Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b39813b

Browse files
committed
fix(ui): surface ClickHouse error message providing a bit of advice to the user.
1 parent 34c2a29 commit b39813b

File tree

5 files changed

+41
-43
lines changed

5 files changed

+41
-43
lines changed

packages/shared/src/server/repositories/clickhouse.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import {
1818

1919
/**
2020
* Custom error class for ClickHouse resource-related errors
21-
* Provides actionable advice for users
2221
*/
2322
// Error type configuration map
2423
const ERROR_TYPE_CONFIG: Record<
@@ -38,22 +37,21 @@ const ERROR_TYPE_CONFIG: Record<
3837
},
3938
};
4039

41-
const ERROR_ADVICE_MESSAGE = [
42-
"Database resource limit exceeded. Please use more specific filters or a shorter time range. We are continuously improving our API performance.",
43-
"See https://langfuse.com/docs/api-and-data-platform/features/public-api for more details.",
44-
].join("\n");
45-
4640
type ErrorType = keyof typeof ERROR_TYPE_CONFIG;
4741

4842
export class ClickHouseResourceError extends Error {
43+
static ERROR_ADVICE_MESSAGE = [
44+
"Database resource limit exceeded.",
45+
"Please use more specific filters or a shorter time range.",
46+
"We are continuously improving our API performance.",
47+
].join(" ");
48+
4949
public readonly errorType: ErrorType;
50-
public readonly displayMessage: string;
5150

5251
constructor(errType: ErrorType, originalError: Error) {
5352
super(originalError.message, { cause: originalError });
5453
this.name = "ClickHouseResourceError";
5554
this.errorType = errType;
56-
this.displayMessage = ERROR_ADVICE_MESSAGE;
5755
// Preserve the original stack trace if available
5856
if (originalError.stack) {
5957
this.stack = originalError.stack;

web/src/__tests__/async/repositories/clickhouse-resource-errors.servertest.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@ import {
55
} from "@langfuse/shared/src/server";
66
import { fail } from "assert";
77

8-
const ERROR_ADVICE_PART =
9-
" Please use more specific filters or a shorter time range.";
10-
118
describe("ClickHouse Resource Error Handling", () => {
129
describe("queryClickhouse", () => {
1310
describe("Error transformation with throwIf", () => {
@@ -21,7 +18,6 @@ describe("ClickHouse Resource Error Handling", () => {
2118
} catch (error: any) {
2219
expect(error).toBeInstanceOf(ClickHouseResourceError);
2320
expect(error.errorType).toBe("MEMORY_LIMIT");
24-
expect(error.displayMessage).toContain(ERROR_ADVICE_PART);
2521
}
2622
});
2723

@@ -35,7 +31,6 @@ describe("ClickHouse Resource Error Handling", () => {
3531
} catch (error: any) {
3632
expect(error).toBeInstanceOf(ClickHouseResourceError);
3733
expect(error.errorType).toBe("OVERCOMMIT");
38-
expect(error.displayMessage).toContain(ERROR_ADVICE_PART);
3934
}
4035
});
4136

@@ -49,7 +44,6 @@ describe("ClickHouse Resource Error Handling", () => {
4944
} catch (error: any) {
5045
expect(error).toBeInstanceOf(ClickHouseResourceError);
5146
expect(error.errorType).toBe("TIMEOUT");
52-
expect(error.displayMessage).toContain(ERROR_ADVICE_PART);
5347
}
5448
});
5549

@@ -185,8 +179,6 @@ describe("ClickHouse Resource Error Handling", () => {
185179
const resourceError = wrappedError as ClickHouseResourceError;
186180
if (shouldBeResourceError && errorType) {
187181
expect(resourceError.errorType).toBe(errorType);
188-
expect(resourceError.displayMessage).toBeDefined();
189-
expect(resourceError.displayMessage.length).toBeGreaterThan(0);
190182
}
191183
});
192184
},

web/src/__tests__/withMiddlewares.servertest.ts

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -202,18 +202,11 @@ describe("withMiddlewares error handling", () => {
202202

203203
await handler(req, res);
204204

205-
expect(res._getStatusCode()).toBe(400);
205+
expect(res._getStatusCode()).toBe(524);
206206
const jsonData = JSON.parse(res._getData());
207-
expect(jsonData).toMatchObject({
208-
message: resourceError.displayMessage,
209-
error: "Too much data requested",
210-
});
211-
212-
expect(logger.error).toHaveBeenCalledWith(
213-
"ClickHouse resource limit exceeded",
214-
expect.objectContaining({
215-
errorType: "MEMORY_LIMIT",
216-
}),
207+
expect(jsonData["message"]).toBeDefined();
208+
expect(jsonData["message"]).toContain(
209+
ClickHouseResourceError.ERROR_ADVICE_MESSAGE,
217210
);
218211
});
219212
});

web/src/features/public-api/server/withMiddlewares.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ const defaultHandler = () => {
2929
throw new MethodNotAllowedError();
3030
};
3131

32+
const CH_ERROR_ADVICE_FULL = [
33+
ClickHouseResourceError.ERROR_ADVICE_MESSAGE,
34+
"See https://langfuse.com/docs/api-and-data-platform/features/public-api for more details.",
35+
].join("\n");
36+
3237
export function withMiddlewares(handlers: Handlers) {
3338
return async (req: NextApiRequest, res: NextApiResponse) => {
3439
const ctx = contextWithLangfuseProps({
@@ -80,13 +85,13 @@ export function withMiddlewares(handlers: Handlers) {
8085

8186
logger.error("ClickHouse resource limit exceeded", {
8287
errorType: resourceError.errorType,
83-
originalMessage: error.message,
84-
displayMessage: resourceError.displayMessage,
88+
message: resourceError.message,
89+
suggestion: CH_ERROR_ADVICE_FULL,
8590
});
8691

87-
return res.status(400).json({
88-
message: resourceError.displayMessage,
89-
error: "Too much data requested",
92+
return res.status(524).json({
93+
message: CH_ERROR_ADVICE_FULL,
94+
error: "Request is taking too long to process.",
9095
});
9196
}
9297

web/src/server/api/trpc.ts

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ import {
8787
logger,
8888
addUserToSpan,
8989
contextWithLangfuseProps,
90+
ClickHouseResourceError,
9091
} from "@langfuse/shared/src/server";
9192

9293
import { AdminApiAuthService } from "@/src/ee/features/admin-api/server/adminApiAuth";
@@ -138,17 +139,26 @@ const withErrorHandling = t.middleware(async ({ ctx, next }) => {
138139
);
139140
}
140141

141-
// Throw a new TRPC error with:
142-
// - The same error code as the original error
143-
// - Either the original error message OR "Internal error" if it's an INTERNAL_SERVER_ERROR
144-
res.error = new TRPCError({
145-
code: res.error.code,
146-
cause: null, // do not expose stack traces
147-
message:
148-
res.error.code !== "INTERNAL_SERVER_ERROR"
149-
? res.error.message
150-
: "Internal error",
151-
});
142+
if (res.error.cause instanceof ClickHouseResourceError) {
143+
// Surface ClickHouse errors using an advice message
144+
// which is supposed to provide a bit of guidance to the user.
145+
res.error = new TRPCError({
146+
code: "TIMEOUT",
147+
message: ClickHouseResourceError.ERROR_ADVICE_MESSAGE,
148+
});
149+
} else {
150+
// Throw a new TRPC error with:
151+
// - The same error code as the original error
152+
// - Either the original error message OR "Internal error" if it's an INTERNAL_SERVER_ERROR
153+
res.error = new TRPCError({
154+
code: res.error.code,
155+
cause: null, // do not expose stack traces
156+
message:
157+
res.error.code !== "INTERNAL_SERVER_ERROR"
158+
? res.error.message
159+
: "Internal error",
160+
});
161+
}
152162
}
153163

154164
return res;

0 commit comments

Comments
 (0)