Skip to content

Commit 004e703

Browse files
committed
Pagination fix
1 parent afda194 commit 004e703

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

apps/webapp/app/presenters/v3/ErrorsListPresenter.server.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,13 @@ export type ErrorOccurrenceActivity = ErrorOccurrences["data"][string];
6161
type ErrorGroupCursor = {
6262
occurrenceCount: number;
6363
fingerprint: string;
64+
taskIdentifier: string;
6465
};
6566

6667
const ErrorGroupCursorSchema = z.object({
6768
occurrenceCount: z.number(),
6869
fingerprint: z.string(),
70+
taskIdentifier: z.string(),
6971
});
7072

7173
function encodeCursor(cursor: ErrorGroupCursor): string {
@@ -191,19 +193,22 @@ export class ErrorsListPresenter extends BasePresenter {
191193
);
192194
}
193195

194-
// Cursor-based pagination (sorted by occurrence_count DESC)
196+
// Cursor-based pagination (sorted by occurrence_count DESC, then fingerprint, then task)
195197
const decodedCursor = cursor ? decodeCursor(cursor) : null;
196198
if (decodedCursor) {
197199
queryBuilder.having(
198-
"(occurrence_count < {cursorOccurrenceCount: UInt64} OR (occurrence_count = {cursorOccurrenceCount: UInt64} AND error_fingerprint < {cursorFingerprint: String}))",
200+
`(occurrence_count < {cursorOccurrenceCount: UInt64}
201+
OR (occurrence_count = {cursorOccurrenceCount: UInt64} AND error_fingerprint < {cursorFingerprint: String})
202+
OR (occurrence_count = {cursorOccurrenceCount: UInt64} AND error_fingerprint = {cursorFingerprint: String} AND task_identifier < {cursorTaskIdentifier: String}))`,
199203
{
200204
cursorOccurrenceCount: decodedCursor.occurrenceCount,
201205
cursorFingerprint: decodedCursor.fingerprint,
206+
cursorTaskIdentifier: decodedCursor.taskIdentifier,
202207
}
203208
);
204209
}
205210

206-
queryBuilder.orderBy("occurrence_count DESC, error_fingerprint DESC");
211+
queryBuilder.orderBy("task_identifier DESC, error_fingerprint DESC, occurrence_count DESC");
207212
queryBuilder.limit(pageSize + 1);
208213

209214
const [queryError, records] = await queryBuilder.execute();
@@ -222,6 +227,7 @@ export class ErrorsListPresenter extends BasePresenter {
222227
nextCursor = encodeCursor({
223228
occurrenceCount: lastError.occurrence_count,
224229
fingerprint: lastError.error_fingerprint,
230+
taskIdentifier: lastError.task_identifier,
225231
});
226232
}
227233

@@ -364,10 +370,16 @@ export class ErrorsListPresenter extends BasePresenter {
364370
if (queryError || !records) return result;
365371

366372
for (const record of records) {
367-
result.set(record.error_fingerprint, {
368-
firstSeen: parseClickHouseDateTime(record.first_seen),
369-
lastSeen: parseClickHouseDateTime(record.last_seen),
370-
});
373+
const firstSeen = parseClickHouseDateTime(record.first_seen);
374+
const lastSeen = parseClickHouseDateTime(record.last_seen);
375+
const existing = result.get(record.error_fingerprint);
376+
377+
if (existing) {
378+
if (firstSeen < existing.firstSeen) existing.firstSeen = firstSeen;
379+
if (lastSeen > existing.lastSeen) existing.lastSeen = lastSeen;
380+
} else {
381+
result.set(record.error_fingerprint, { firstSeen, lastSeen });
382+
}
371383
}
372384

373385
return result;

0 commit comments

Comments
 (0)