Skip to content

[Messenger] Add method HandlerFailedException::getNestedExceptionOfClass #34704

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 11, 2020

Conversation

tyx
Copy link
Contributor

@tyx tyx commented Nov 29, 2019

Q A
Branch? master
Bug fix? no
New feature? yes
Deprecations? no
License MIT
Doc PR in progress

I have many times use this kind of code on my own development. It helps when dealing with specific exception through a Messenger usage.

Example in an ExceptionListener, the exception you get could be a HandlerFailedException but you want a specific treatment when the original exception is different (like a RedirectResponse, or Http error code different).

edit: I finally also added a getNestedExceptionOfClass that could be useful too

@tyx tyx force-pushed the feature/has-nested-exception branch from cdbe8c8 to 18981b6 Compare November 29, 2019 16:45
@tyx tyx changed the title [Messenger] Add method HandlerFailedException::hasNestedExceptionOfClass [Messenger] Add method HandlerFailedException::(has|get)NestedExceptionOfClass Nov 29, 2019

public function hasNestedExceptionOfClass(string $exceptionClassName): bool
{
return 0 < \count($this->getNestedExceptionOfClass($exceptionClassName));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about this method: it looks like calling for double computation of the logic.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi ! You mean, I should remove it or you have an idea to improve it ?

Copy link
Member

@Nyholm Nyholm Jan 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we have 20 exceptions, and the first one is $exceptionClassName, we will still count the other 19. Right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you please remove this method?

return array_filter(
$this->exceptions,
function ($exception) use ($exceptionClassName) {
return \get_class($exception) === $exceptionClassName;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be an exact match, or an is_a() check?
you feature request looks like an instanceof check. This would mean is_a() here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok good catch. In my mind it was a is_a check but I should admin an instanceof looks better indeed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets use is_a() instead.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add some related test cases also.

Copy link
Member

@Nyholm Nyholm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes please! I can see this is somewhat useful.

I often write code like:

try {
    $this->bus->dispatch($command);
} catch (HandlerFailedException $e) {
    $exception = $e->getPrevious();
    if ($exception instanceof FooException) {
        // Handle it one way
    } else {
        // I dont know what to do... 
        throw $e;
    }
}

Now I can write:

try {
    $this->bus->dispatch($command);
} catch (HandlerFailedException $e) {
    if ($e->hasNestedExceptionOfClass(FooException::class)) {
        // Handle it one way
    } else {
        // I dont know what to do...
        throw $e;
    }
}


public function hasNestedExceptionOfClass(string $exceptionClassName): bool
{
return 0 < \count($this->getNestedExceptionOfClass($exceptionClassName));
Copy link
Member

@Nyholm Nyholm Jan 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we have 20 exceptions, and the first one is $exceptionClassName, we will still count the other 19. Right?

return array_filter(
$this->exceptions,
function ($exception) use ($exceptionClassName) {
return \get_class($exception) === $exceptionClassName;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets use is_a() instead.

@tyx
Copy link
Contributor Author

tyx commented Jan 19, 2020

Hello @Nyholm !

Thanks for the reminder.

Glad to see I'm not alone writing this kind of code ;)

I postponed updating this PR for a long time. I will fix that asap.

@Devristo
Copy link
Contributor

When dispatching a new command from a command handler it could cause additional nesting of HandlerFailedException. For example:

  • HandlerFailedException
    • HandlerFailedException
      • MyCustomException

Is this something we would like to consider?

Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Friendly ping @tyx


public function hasNestedExceptionOfClass(string $exceptionClassName): bool
{
return 0 < \count($this->getNestedExceptionOfClass($exceptionClassName));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you please remove this method?

return array_filter(
$this->exceptions,
function ($exception) use ($exceptionClassName) {
return \get_class($exception) === $exceptionClassName;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add some related test cases also.

@Nyholm
Copy link
Member

Nyholm commented May 12, 2020

A nice little ping again =)

@tyx tyx changed the title [Messenger] Add method HandlerFailedException::(has|get)NestedExceptionOfClass [Messenger] Add method HandlerFailedException::getNestedExceptionOfClass May 12, 2020
@tyx tyx force-pushed the feature/has-nested-exception branch from 18981b6 to 89083e3 Compare May 12, 2020 09:54
@tyx
Copy link
Contributor Author

tyx commented May 12, 2020

Nice timing @Nyholm ;)

I just updated and rebased the PR

@Nyholm
Copy link
Member

Nyholm commented May 12, 2020

Thank you for the update.

I think the current code looks good. Im just curious about something. Im not sure we should change anything, but I just want to ask. Is there someway we can stop dealing with arrays?

Maybe Im just interested in the first error. Ie:

try {
    $this->bus->dispatch($command);
} catch (HandlerFailedException $e) {
    if (null !== $exception = $e->getFirstNestedExceptionOfClass(FooException::class)) {
        echo $exception->getMessage()
    } else {
        throw $e;
    }
}

The vast majority of the times, I get an HandlerFailedExcpetion with just a single exception in it. Do we care?

@tyx tyx force-pushed the feature/has-nested-exception branch from 89083e3 to 99d8371 Compare May 13, 2020 08:59
To know if specific exception are the origin of messenger failure
@tyx tyx force-pushed the feature/has-nested-exception branch from 99d8371 to e0dd84b Compare May 13, 2020 08:59
@tyx
Copy link
Contributor Author

tyx commented May 13, 2020

Regarding the PR I made a small tweak to ensure returning an array with correct indexes (and update test).

For your point @Nyholm you're totally right. I do the same !

May be we could also add another method to get only the first occurence as sugar ?

@fabpot
Copy link
Member

fabpot commented Aug 11, 2020

Thank you @tyx.

@fabpot fabpot merged commit e7617da into symfony:master Aug 11, 2020
@tyx tyx deleted the feature/has-nested-exception branch August 11, 2020 18:56
@nicolas-grekas nicolas-grekas modified the milestones: next, 5.2 Oct 5, 2020
@fabpot fabpot mentioned this pull request Oct 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants