@@ -22,14 +22,19 @@ export class SqsQueue<TJobMap = Record<string, any>> extends Queue<
2222 TJobMap ,
2323 SqsJobRequest < any >
2424> {
25+ #onFailure: "delete" | "leaveInQueue"
26+
2527 constructor (
2628 private client : SQSClient ,
2729 private queueUrl : string ,
28- options : QueueOptions = { }
30+ options : QueueOptions & { onFailure : "delete" | "leaveInQueue" } = {
31+ onFailure : "delete" ,
32+ }
2933 ) {
3034 super ( options ) ;
3135 // SQS supports long polling via WaitTimeSeconds
3236 this . supportsLongPolling = true ;
37+ this . #onFailure = options . onFailure ;
3338 }
3439
3540 protected async pushMessage ( payload : string , meta : JobMeta ) : Promise < string > {
@@ -57,7 +62,7 @@ export class SqsQueue<TJobMap = Record<string, any>> extends Queue<
5762 DelaySeconds : meta . delay || 0 ,
5863 MessageAttributes : messageAttributes ,
5964 } ) ;
60-
65+
6166 const result = await this . client . send ( command ) ;
6267
6368 if ( ! result . MessageId ) {
@@ -73,7 +78,7 @@ export class SqsQueue<TJobMap = Record<string, any>> extends Queue<
7378 WaitTimeSeconds : timeout ,
7479 MessageAttributeNames : [ "All" ] ,
7580 } ) ;
76-
81+
7782 const result = await this . client . send ( command ) ;
7883
7984 if ( ! result . Messages || result . Messages . length === 0 ) {
@@ -105,7 +110,7 @@ export class SqsQueue<TJobMap = Record<string, any>> extends Queue<
105110 ReceiptHandle : message . ReceiptHandle ,
106111 VisibilityTimeout : meta . ttr ,
107112 } ) ;
108-
113+
109114 await this . client . send ( visibilityCommand ) ;
110115 }
111116
@@ -119,21 +124,43 @@ export class SqsQueue<TJobMap = Record<string, any>> extends Queue<
119124 } ;
120125 }
121126
122- protected async release ( message : QueueMessage ) : Promise < void > {
127+ protected async completeJob ( message : QueueMessage ) : Promise < void > {
123128 if ( ! message . meta . receiptHandle ) {
124129 throw new Error (
125- "Cannot release SQS message: receiptHandle is missing from metadata"
130+ "Cannot complete SQS message: receiptHandle is missing from metadata"
126131 ) ;
127132 }
128133
129134 const deleteCommand = new DeleteMessageCommand ( {
130135 QueueUrl : this . queueUrl ,
131136 ReceiptHandle : message . meta . receiptHandle ,
132137 } ) ;
133-
138+
134139 await this . client . send ( deleteCommand ) ;
135140 }
136141
142+ protected async failJob (
143+ message : QueueMessage ,
144+ error : unknown
145+ ) : Promise < void > {
146+ if ( this . #onFailure === "leaveInQueue" ) {
147+ if ( ! message . meta . receiptHandle ) {
148+ throw new Error (
149+ "Cannot fail SQS message: receiptHandle is missing from metadata"
150+ ) ;
151+ }
152+
153+ // For SQS, we delete failed messages too since SQS doesn't track failure states
154+ // Future enhancement could send to a dead letter queue
155+ const deleteCommand = new DeleteMessageCommand ( {
156+ QueueUrl : this . queueUrl ,
157+ ReceiptHandle : message . meta . receiptHandle ,
158+ } ) ;
159+
160+ await this . client . send ( deleteCommand ) ;
161+ }
162+ }
163+
137164 async status ( id : string ) : Promise < JobStatus > {
138165 throw new Error ( "SQS does not support status" ) ;
139166 }
0 commit comments