logo

Let your command fail loudly instead of throwing

A small change that made my validation easy to test

Joel Clermont
Joel Clermont
2026-06-23

I had previously shared an annoyance I ran into testing a command with validation logic. Claude Code tried to work around it by putting exception handling logic in my test, but I rejected that solution.

My solution was to improve the command and not just paper over the exception in my test.

Instead of just calling validated() and letting it throw, I first check whether validation fails and gracefully handle it:

if ($validator->fails()) {
    collect($validator->errors()->all())
        ->each(fn ($message) => $this->error($message));

    return static::FAILURE;
}

// this will never throw an exception now
$arguments = $validator->validated();

Now the command runs without blowing up, and it produces clear error output and an exit code to tell the caller what went wrong.

This improved logic not only produces a better user experience, it also solves my testing friction from the unhandled exception.

Instead of introducing exception handling to my test, I have a clean chained assertion:

$this->artisan(TipsCreateBook::class, ['from' => ''])
    ->assertExitCode(Command::FAILURE)
    ->expectsOutput('The from field is required.');

I like this solution a lot better!

Here to help,

Joel

P.S. We go deep on testing techniques like this in our hands-on workshop. Check out our testing workshop.

Toss a coin in the jar if you found this helpful.
Want a tip like this in your inbox every weekday? Sign up below 👇🏼
email
No spam. Only real-world advice.