[9.x] Return non-zero exit code for uncaught exceptions - #46541
Conversation
|
Honestly for a simple change I would just leave all tests unchanged. Just creates more maintenance overhead than it's worth. |
| } | ||
|
|
||
| if ($uncaught) { | ||
| exit(1); |
There was a problem hiding this comment.
Wouldn't this cause Octane to exit the worker on every uncaught exception, which is not desired?
There was a problem hiding this comment.
good question. That could be the case yes.
Anyhow, there is no way to say to php "exit with exitCode=1 on your own accord (when its time to exit)". AFAIK you must call exit(1) yourself which will then still call any remaining __destruct() listeners and shutdown handlers.
There was a problem hiding this comment.
I moved the exit(1) call a few lines up now (inside the $app->runningInConsole() since this is a command line related issue)
There was a problem hiding this comment.
Octane workers still will have $app->runningInConsole() === true since it is an artisan command.
Octane worker emits APP_RUNNING_IN_CONSOLE=false so should be okay.
|
@taylorotwell I prefer to leave the test in since the behaviour does need to be tested. If you have a faster/cleaner way to test this with less code then by all means :) One way or another you need to call an external process with a |
|
@crynobone do you have any idea on how to rewrite the testcase using the testbench such that I can test the exitcode for running an artisan command? |
|
@bert-w Can you share an artisan command example? |
|
@crynobone in essence doing the following: /** @var \Illuminate\Foundation\Console\Kernel $kernel */
$exitCode = $kernel->call('throw-exception-command');However since the command is meant to throw and I want to test the exitcode, this call must happen as a separate process or else the testcase itself will throw the exception. This PR currently includes a wrapper to create an explicit |
Use `PhpProcess` to run PHP script in isolation to verify `exit()`
|
Is there any way an application could enter this section of code without being in an unrecoverable / fatal error state? In other words, is this going to break any applications that could have possible kept executing code after this |
|
I don't see how that could be possible since that function is set using Then once The only destructor being called after this in a default Laravel app is the Monolog handler itself, but whether it is called because of an |
|
@bert-w @taylorotwell @crynobone This PR unintentionally introduced the exit(1) call in a method (handleException) used also for register_shutdown_function, making any other shutdown functions to not be executed. We discovered this while doing a POC for this issue #58207 (comment) Question is: Is the exit(1) needed in the php error case? Maybe not. |
I thought about this for a moment: according to the manual https://www.php.net/manual/en/function.register-shutdown-function.php a shutdown handler can register its own shutdown handler as well:
So perhaps instead of calling |
|
@bert-w that works, but is it needed in the fatal error case? |
This is a fix for #46306.
Any uncaught exceptions inside the exception handler now explicity exit with code 1, indicating an error state. A test has been included to test for the correct exit code in case of an uncaught exception and in the case of successful execution.
EDIT: thanks to Crynobone for cleaning up the testcase to work neatly with the testbench