Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[Messenger] Throw exceptions in BatchHandler in sync mode #49654

Copy link
Copy link
Open
@DavidBadura

Description

@DavidBadura
Issue body actions

Description

I modified my command handler to use the BatchHandler. I noticed that my handler now behaves differently in sync mode, if you pass null in Acknowledger, than before. In async mode everything runs perfectly.

According to the feature (#43354), the handler in sync mode should work the same as before without the BatchHandler/BatchHandlerTrait.

But if an exception is thrown in the handler, it will be swallowed by the BatchHandlerTrait (sync mode). In other words, the command is always successful, as far as I can tell. Maybe this could also be defined as a bug, because the command always succeeds, which it shouldn't be.

To show this briefly, my Command Batch Handler process method looks like this:

 private function process(array $jobs): void
{
    foreach ($jobs as [$message, $ack]) {
        try {

            // do something...

            $ack->ack();
        } catch (Throwable $e) {
            $ack->nack($e);
        }
    }
}

The following happens when the handler is executed (sync mode):

  • add message in jobs
  • force flush (trigger process)
  • execute process
  • developer need to iterate over the messages (in this case, one message)
    • ack if success
    • nack if error/exception
  • get Acknowledger result

Here is the relevant code place:

if (null === $ack) {
    $ack = new Acknowledger(get_debug_type($this));
    $this->jobs[] = [$message, $ack];
    $this->flush(true);

    return $ack->getResult();
}

The problem now is that nack wasn't handled properly. The $ack->getResult() is always null in case of an error. But what corresponds to a successful command. In my opinion, the following is missing:

if (null === $ack) {
    $ack = new Acknowledger(get_debug_type($this));
    $this->jobs[] = [$message, $ack];
    $this->flush(true);
    
    $error = $ack->getError();
    if ($error) {
        throw $error;
    }

    return $ack->getResult();
}

It is checked if there is an error in the acknowledger, if so, then this is thrown. Otherwise the result is returned (success).

If it's confirmed as a bug or feature, I'm more than happy to do a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.