Skip to content

Commit f8733b3

Browse files
committed
Retry replication unless the error is a known non-retry error
Flip the strategy to retry by default
1 parent d80af53 commit f8733b3

File tree

1 file changed

+30
-19
lines changed

1 file changed

+30
-19
lines changed

apps/webapp/app/services/runsReplicationService.server.ts

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -515,11 +515,11 @@ export class RunsReplicationService {
515515
} catch (error) {
516516
lastError = error instanceof Error ? error : new Error(String(error));
517517

518-
// Check if this is a retryable connection error
519-
if (this.#isRetryableConnectionError(lastError)) {
520-
const delay = this.#calculateConnectionRetryDelay(attempt);
518+
// Check if this is a retryable error
519+
if (this.#isRetryableError(lastError)) {
520+
const delay = this.#calculateRetryDelay(attempt);
521521

522-
this.logger.warn(`Retrying RunReplication insert due to connection error`, {
522+
this.logger.warn(`Retrying RunReplication insert due to error`, {
523523
operationName,
524524
flushId,
525525
attempt,
@@ -538,26 +538,37 @@ export class RunsReplicationService {
538538
return [lastError, null];
539539
}
540540

541-
// New method to check if an error is a retryable connection error
542-
#isRetryableConnectionError(error: Error): boolean {
541+
// Retry all errors except known permanent ones
542+
#isRetryableError(error: Error): boolean {
543543
const errorMessage = error.message.toLowerCase();
544-
const retryableConnectionPatterns = [
545-
"socket hang up",
546-
"econnreset",
547-
"connection reset",
548-
"connection refused",
549-
"connection timeout",
550-
"network error",
551-
"read econnreset",
552-
"write econnreset",
553-
"timeout",
544+
545+
// Permanent errors that should NOT be retried
546+
const permanentErrorPatterns = [
547+
"authentication failed",
548+
"permission denied",
549+
"invalid credentials",
550+
"table not found",
551+
"database not found",
552+
"column not found",
553+
"schema mismatch",
554+
"invalid query",
555+
"syntax error",
556+
"type error",
557+
"constraint violation",
558+
"duplicate key",
559+
"foreign key violation",
554560
];
555561

556-
return retryableConnectionPatterns.some((pattern) => errorMessage.includes(pattern));
562+
// If it's a known permanent error, don't retry
563+
if (permanentErrorPatterns.some((pattern) => errorMessage.includes(pattern))) {
564+
return false;
565+
}
566+
567+
// Retry everything else
568+
return true;
557569
}
558570

559-
// New method to calculate retry delay for connection errors
560-
#calculateConnectionRetryDelay(attempt: number): number {
571+
#calculateRetryDelay(attempt: number): number {
561572
// Exponential backoff: baseDelay, baseDelay*2, baseDelay*4, etc.
562573
const delay = Math.min(
563574
this._insertBaseDelayMs * Math.pow(2, attempt - 1),

0 commit comments

Comments
 (0)