Just F*cking Throw

Look - we need to f*cking talk.

Somewhere along the way, a bunch of Very Serious® engineers decided that returning Errors as Values like it’s 1978 was The One True Way™. Suddenly, every function signature is a hostage negotiation, every call site is a choose-your-own-adventure, and your “happy path” is buried under a landfill of if err != nul checks like a crime scene that nobody wants to clean up.

Stop it.

Stop pretending that manually threading error objects through every line of code is some kind of moral virtue. Stop pretending that your 400-line function is “more explicit” because you’ve lovingly copy-pasted a (somehow) bespoke error-passing Rube Goldberg machine.

You know what is explicit?

Just F*cking Throwing

The F*cking Points

Your “Happy Path” is Supposed to be Happy

Your code should read like what it does, not like what it might fail to do if the universe collapses in any predictable way.

When you use exceptions, your happy path is clean, direct, and readable. It says:

“Here is the thing I want to do.”

When you use Errors as Values, your happy path says:

“Here is the thing I want to do, unless this, or this, or this, or…”

It’s like trying to read a recipe where every step ends with:

Just F*cking Throw

Error Passing is Noise

You’re not a monk in a monastery of monads. You’re writing software.

And software has errors.

And errors should be handled where they matter, not shoved down the throat of every function the call stack like some kind of bureaucratic form letter.

Exceptions let you say:

“If something goes wrong, jump to the part of the code that actually cares.”

Errors as Values force you to say:

“If something goes wrong, please escort this error to the next desk, where it will be stamped, initialed, and forwarded to the next desk, where it will be stamped initialed…”

Congratulations, you’ve reinvented the DMV.

Just F*cking Throw

Exceptions Yield Shorter Code

Yes, code size matters.

You know what’s easy to maintain?

Short code.

You know what’s easier to read?

Short code.

You know whats easier to reason about?

Short code.

You know what exceptions give you?

Short code.

Meanwhile, Errors as Values give you:

If you think verbosity is clarity, I have a 900-page legal contract you’re going to love.

Just F*cking Throw

“But Exceptions Hide Control Flow!”

No, idiot. Your Error-Return spaghetti hides control flow.

With exceptions, you don’t have to recurse backwards through your code to understand where the error is handled - it will always be handled in the closest catch block. Exceptions make control flow clear:

Errors as Values force you to recurse, line by line, to determine how and where your error is handled, where it is passed, and what happens in between. Errors as Values convolute control flow:

It’s like reading a book where every paragraph ends with:

“Turn to page 47 if the dragon is still alive.”

Just F*cking Throw

“But Exceptions are Slow!”

Oh no, the computer might have to do work when something exceptional happens!

If your program is throwing exceptions so often that performance matters, your problem is not exceptions.

Your problem is your program.

Just F*cking Throw

“But Go uses Errors as Values!”

Yes. And Go also has no generis for a decade, a for loop that looks like a 1990s C tutorial, and a type system that politely excuses itself whenever things get interesting.

You don’t have to emulate every language’s worst idea (the seeming goal of in-vogue languages like Go and Rust).

Just F*cking Throw

“But Exceptions should be Checked Exceptions!”

The assertion that exceptions must be ‘checked’ and each one explicitly handled is wildly stupid. Exceptions are hierarchial, and can be caught at any specificity.

Checked exceptions totally mangle this entire mentality by infecting it with “Errors as Values” thinking.

Rule of thumb:

For example - if you encounter a db deadlock - then add an explicit try{}catch() around the db query method and catch that specific exception type, then implement your retry logic. Congrats, you’ve elegantly and clearly handled your error case without the compiler forcing things down your throat.

“But checked exceptions would have forced you to implement that from the beginning!”

Thinking you know how to handle an exception before encountering it is usually a dumb thought. And it’s a waste of time if you never actually encounter that exception. Write robust code that fails gracefully. Fix those failures that occur elegantly.

Just F*cking Throw

Exceptions are the Right Tool for the Job

Exceptions are Exceptional.

Exceptional things should use exceptions. This is not complicated.

If your function fails, throw.
If your caller cares, catch.
If your caller doesn’t care, don’t catch.

This is how grown-up languages work.

JUST. F*CKING. THROW.

Stop cluttering your code with error-passing bureaucracy.
Stop pretending that verbosity is a virtue.
Stop writing your happy path like a legal deposition.

Write clean code.
Write readable code.
Write code that does what it says.

And when something goes wrong?

Just F*cking Throw