@@ -442,22 +442,28 @@ def _reduce(data: Iterable[In], context: IContextManager | None = None) -> Itera
442442 def catch [U ](
443443 self ,
444444 sub_pipeline_builder : Callable [["Transformer[Out, Out]" ], "Transformer[Out, U]" ],
445- on_error : ChunkErrorHandler [Out , U ] | None = None ,
445+ on_error : ChunkErrorHandler [Out , None ] | None = None ,
446446 ) -> "Transformer[In, U]" :
447447 """Isolate a sub-pipeline in a chunk-based try-catch block.
448448
449449 If the sub-pipeline fails for a chunk, the on_error handler is invoked.
450450
451451 Args:
452452 sub_pipeline_builder: A function that builds the sub-pipeline to protect.
453- on_error: Optional error handler for when the sub-pipeline fails.
453+ on_error: A picklable error handler for when the sub-pipeline fails.
454+ It takes a chunk, exception, and context, and must return a
455+ replacement chunk (`list[U]`). If not provided, an empty
456+ list is returned on error.
454457
455458 Returns:
456459 A transformer with error handling applied.
457460 """
458461
459- if on_error :
460- self .on_error (on_error ) # type: ignore
462+ # Use the global error handler if it exists, otherwise create an internal one
463+ catch_error_handler = self .error_handler
464+
465+ if on_error is not None :
466+ catch_error_handler .on_error (on_error ) # type: ignore
461467
462468 # Create a blank transformer for the sub-pipeline
463469 temp_transformer = createTransformer (_type_hint = ..., chunk_size = self .chunk_size ) # type: ignore
@@ -466,13 +472,18 @@ def catch[U](
466472 sub_pipeline = sub_pipeline_builder (temp_transformer )
467473 sub_transformer_func = sub_pipeline .transformer
468474
475+ # This 'operation' function is now picklable. It only closes over
476+ # `sub_transformer_func` and `catch_error_handler`, both of which are
477+ # picklable, and it no longer references `self`.
469478 def operation (chunk : list [Out ], ctx : IContextManager ) -> list [U ]:
470479 try :
471- # Attempt to process the whole chunk with the sub-pipeline
480+ # Attempt to process the chunk with the sub-pipeline
472481 return sub_transformer_func (chunk , ctx )
473482 except Exception as e :
474- # On failure, delegate to the chunk-based error handler
475- self .error_handler .handle (chunk , e , ctx )
483+ # Call the error handler (which may include both global and local handlers)
484+ catch_error_handler .handle (chunk , e , ctx )
485+
486+ # Return an empty list as the default behavior after handling the error
476487 return []
477488
478489 return self ._pipe (operation ) # type: ignore
0 commit comments