I’am kind of new to laravel and currently working with pipelines. As I know, if one step inside the Pipeline fail, the whole Pipeline get stopped at that step. That is exactly what I want, so I’am fine with that.
But I want to handle the given Exception from the failing step. And now is the question, how? I can’t find anything about that..
So my code for the pipeline looks like this (e.g.):
final readonly class CreateInboundPlanPipeline
{
public function __invoke(DataContainer $container, Closure $next): DataContainer
{
//Init Normalizer
$normalizer = new FBAInboundNormalizer();
//Do something with $container
$items = json_decode($container->__get('initialrequest')->input('items'));
$response = $normalizer->createInboundPlan($items, $container->__get('initialrequest'));
if($response['success']){
$extendContainer = $container;
$extendContainer->inboundplanid = $response["inboundPlanId"];
$extendContainer->currentOperationId = $response["operationId"];
}else{
throw new Exception($response["message"]);
}
return $next($extendContainer);
}
}
public function handle(): void
{
$filledContainer = app(Pipeline::class)
->send($this->container)
->through([
CreateInboundPlanPipeline::class,
])
->then(function(){
//Action after Pipeline
//e.g. fill a model or smth
});
}
E.g. if "CreateInboundPlanPipeline" throws an Exception, how could I catch and handle it?
I found the function "handleException" inside the Pipeline, is that the proper way?
Would look like this?
$filledContainer = app(Pipeline::class)
->send($this->container)
->through([
CreateInboundPlanPipeline::class,
])
->then(function(){
//Action after Pipeline
//e.g. fill a model or smth
})
->handleException(function(){
//Handle Exception here
});
2
Answers
You should be able to
try/catch
the pipeline.The
handleException()
method is protected and therefore not to be called aspipe()
,finally()
, andthen()
passing a callable but to be overwritten by extending the Pipeline class similar to thehandleCarry()
method.As the default
handleException()
implementation just throws the exception (it would void thethen($destination)
$destination()
invocation), you can handle any exception in the pipelines’ first pipe:Discussion:
As you are currently debugging a lot, you can then move that along step-by-step ("pipe-by-pipe") by putting it between other
->pipe(...)
or->through(...)
calls.The
finally($callback)
will be invoked regardless if you catch, bubble or re-throw the catched throwable.If you always want to handle exceptions for a pipeline consider to create a subtype and implement the
handleException()
method, it offers more fine-grained exception handling during pipeline execution.In general it might be more beneficial to not handle exceptions at all and just let them pass through and make them void the pipeline and then handle failed pipelines at a different place.
E.g. as the other answer by Bennett demonstrates, it is possible to try/catch the
whole ->then()
call, but similar as shown in the variation perpipe()
here, there is not much use of it apart it shows a more fine-grained option of the same thing: PHP try/catch exception handling.It is perhaps better not to debug and instead let the pipeline throw and fail. Pipelines are well-designed for that.