logo

A test that needs a try/catch is a warning sign

My coding agent suggested code that worked but still felt wrong

Joel Clermont
Joel Clermont
2026-06-22

In the past, I made the case for validating Artisan command input.

As always, I like to test my validation logic, but this surfaced a new point of friction. There aren't nice test helpers for validation errors in a command like there are with a controller.

In my command, I was calling the validated() method on my validator instance, which throws a ValidationException.

This same mechanism in a controller is fine, because the framework has a special handler for that exception, forming it into a nice 422 response you can write clean test assertions against.

But in a command, that exception just bubbles up unhandled, so my test blew up before I could assert anything.

Before I get to the solution, I want to use today's tip to highlight a different pattern I continue to observe.

I was working with Claude Code, and as usual, it had a fix ready for my issue. Its approach was to alter my test to wrap the command call in a try/catch and then assert on the exception:

try {
    $this->artisan(TipsCreateBook::class, ['from' => '', /* ... */]);

    $this->fail('Expected a validation exception.');
} catch (ValidationException $e) {
    $this->assertContains('The from field is required.', $e->errors()['from']);
}

To be fair, this solution does let the test pass, but this feels like a horrible idea to me. Shoving control flow inside a test is not something I would ever do.

This is a good example of a coding agent handing me something that technically works but actually steers me toward worse code.

In addition, "fixing" the test in this way also ignores a bigger issue. This difficulty in testing the command validation is a glaring reminder that the command offers a terrible user experience. Do I really want a command to blow up for a validation error?

As a side note, I did briefly consider switching the command over to Laravel's prompts, which has much nicer assertions around validation built in, but this command isn't interactive. It takes its arguments up front, and bending it into an interactive shape just to get better test ergonomics felt like another misguided solution.

So I rejected the guidance, confident there must be a better solution that addresses both the test inconvenience and the poor user experience.

To keep this tip from growing any longer, I'll share the simple built-in solution in an upcoming tip. But in the meantime, I think it's worth a reminder that while coding agents are amazing tools, we can't delegate our judgment or taste in how a solution is constructed.

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.