@@ -203,13 +203,75 @@ impl SqsBatchResponse {
203203 /// lambda_runtime::run(service_fn(function_handler)).await
204204 /// }
205205 /// ```
206- pub fn add_failure ( & mut self , message_id : String ) {
206+ pub fn add_failure ( & mut self , message_id : impl Into < String > ) {
207207 self . batch_item_failures . push ( BatchItemFailure {
208- item_identifier : message_id,
208+ item_identifier : message_id. into ( ) ,
209209 #[ cfg( feature = "catch-all-fields" ) ]
210210 other : serde_json:: Map :: new ( ) ,
211211 } ) ;
212212 }
213+
214+ /// Set multiple failed message IDs at once.
215+ ///
216+ /// This is a convenience method for setting all batch item failures in one call.
217+ /// It replaces any previously registered failures.
218+ ///
219+ /// **Important**: This feature requires `FunctionResponseTypes: ReportBatchItemFailures`
220+ /// to be enabled in your Lambda function's SQS event source mapping configuration.
221+ /// Without this setting, Lambda will retry the entire batch on any failure.
222+ ///
223+ /// # Example
224+ ///
225+ /// ```rust,no_run
226+ /// use aws_lambda_events::event::sqs::{SqsEvent, SqsBatchResponse};
227+ /// use lambda_runtime::{service_fn, Error, LambdaEvent};
228+ ///
229+ /// async fn function_handler(
230+ /// event: LambdaEvent<SqsEvent>,
231+ /// ) -> Result<SqsBatchResponse, Error> {
232+ /// let mut failed_ids = Vec::new();
233+ ///
234+ /// for record in event.payload.records {
235+ /// let message_id = record.message_id.clone().unwrap_or_default();
236+ ///
237+ /// // Try to process the message
238+ /// if let Err(e) = process_record(&record).await {
239+ /// println!("Failed to process message {}: {}", message_id, e);
240+ /// failed_ids.push(message_id);
241+ /// }
242+ /// }
243+ ///
244+ /// // Set all failures at once
245+ /// let mut response = SqsBatchResponse::default();
246+ /// response.set_failures(failed_ids);
247+ ///
248+ /// Ok(response)
249+ /// }
250+ ///
251+ /// async fn process_record(record: &aws_lambda_events::event::sqs::SqsMessage) -> Result<(), Error> {
252+ /// // Your message processing logic here
253+ /// Ok(())
254+ /// }
255+ ///
256+ /// #[tokio::main]
257+ /// async fn main() -> Result<(), Error> {
258+ /// lambda_runtime::run(service_fn(function_handler)).await
259+ /// }
260+ /// ```
261+ pub fn set_failures < I , S > ( & mut self , message_ids : I )
262+ where
263+ I : IntoIterator < Item = S > ,
264+ S : Into < String > ,
265+ {
266+ self . batch_item_failures = message_ids
267+ . into_iter ( )
268+ . map ( |id| BatchItemFailure {
269+ item_identifier : id. into ( ) ,
270+ #[ cfg( feature = "catch-all-fields" ) ]
271+ other : serde_json:: Map :: new ( ) ,
272+ } )
273+ . collect ( ) ;
274+ }
213275}
214276
215277#[ non_exhaustive]
@@ -405,4 +467,21 @@ mod test {
405467 assert_eq ! ( response. batch_item_failures[ 0 ] . item_identifier, "msg-1" ) ;
406468 assert_eq ! ( response. batch_item_failures[ 1 ] . item_identifier, "msg-2" ) ;
407469 }
470+
471+ #[ test]
472+ #[ cfg( feature = "sqs" ) ]
473+ fn example_sqs_batch_response_set_failures ( ) {
474+ let mut response = SqsBatchResponse :: default ( ) ;
475+ response. set_failures ( vec ! [ "msg-1" , "msg-2" , "msg-3" ] ) ;
476+
477+ assert_eq ! ( response. batch_item_failures. len( ) , 3 ) ;
478+ assert_eq ! ( response. batch_item_failures[ 0 ] . item_identifier, "msg-1" ) ;
479+ assert_eq ! ( response. batch_item_failures[ 1 ] . item_identifier, "msg-2" ) ;
480+ assert_eq ! ( response. batch_item_failures[ 2 ] . item_identifier, "msg-3" ) ;
481+
482+ // Test that set_failures replaces existing failures
483+ response. set_failures ( vec ! [ "msg-4" . to_string( ) ] ) ;
484+ assert_eq ! ( response. batch_item_failures. len( ) , 1 ) ;
485+ assert_eq ! ( response. batch_item_failures[ 0 ] . item_identifier, "msg-4" ) ;
486+ }
408487}
0 commit comments