Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

First, your categories are not universal. They depend on the language and the runtime. 1. Divide by zero In IEEE floating point you can define it to yield Infinity or NaN and keep going. In some languages it raises an exception. In C with integers you get undefined behavior with no exception at all. If your claim were about a fundamental flaw of code itself, the result would not change across environments. It does. So your category is a policy choice, not a law of nature. 2. Out of bounds In Java you get an IndexOutOfBoundsException. In C you can trample memory and never raise anything. Same code pattern, different outcome. Again this shows your supposed bright line is just a design decision. 3. methodThatDoesNotExist In a statically typed language this is a compile time error and never throws at runtime. In a dynamic language it can throw NoSuchMethod at runtime. Same text, different category, based on tooling. That is not a fundamental metaphysics of exceptions. It is the compiler and runtime drawing the line.

Conclusion from 1 through 3 Your definition of exception as a fundamental flaw collapses the moment we cross a language boundary. What you are calling fundamental is actually configurable convention.

Second, your machine versus human distinction is self defeating.

You say the machine can determine exceptions but only humans can determine bugs. The machine does not determine anything. It executes rules we wrote. If a rule maps a state to raise an exception, the machine raises one. Whether that state is a bug is defined by the spec. If the spec says division by zero must never occur in production, any runtime that hits it is a bug. If the spec says handle it as Infinity, then hitting it is not a bug. The label follows intent and contract, not the instruction pointer.

Obvious example A payment service has a rule that user input must be validated before division. A request slips through with divisor zero and the service throws. That is a bug even if the language designer felt very proud of raising an ArithmeticException. Flip the rule. If the service is specified to accept zero and return a sentinel value, then raising an exception is itself the bug.

Third, the data structure versus concept move does not rescue the argument.

Yes, we all know you can throw an object on purpose. Yes, we all know many libraries create rich exception objects. None of that changes the core point. In a nontrivial system, unhandled exceptions or exceptions raised in states that the spec forbids are bugs by definition. The exception is the transport. The bug is the violation that made the transport fire.

Your own toy example proves it You show an inverted conditional that throws. You say that is not an exception in the conceptual sense. But the system would still page the on call, still fail the request, still violate the acceptance test. Every operator and every customer would call that a bug. You are trying to win by relabeling the alarm as not part of the fire drill.

Fourth, here are obvious scenarios that make the logic clear to anyone.

Elevator Spec: doors must never open between floors. Code hits that state and trips a safety exception. If that ever happens in production, it is a bug. If the safety system decides to log and keep moving instead, and the spec requires a stop, then not throwing is the bug. The exception path is just the messenger.

Bank transfers Spec: never double charge. Off by one posts the same transfer twice. The code throws on the second insert due to a unique constraint. If it throws, the incident is a bug. If it does not throw because the database had no constraint and you silently post two charges, that outcome is a bug. In both cases the presence or absence of an exception is not the category. The spec is the category. The bug is the deviation.

Medical device Spec: sensor readings out of range must be clamped and logged, not crash the loop. If the runtime raises an exception and the loop dies, that exception is the manifestation of a bug. If the runtime never raises and you keep using garbage without logging, that silent path is the bug. Same state space. Different handling. The spec decides which path is the failure.

Toaster Spec: pop after two minutes. The timer arithmetic overflows and you get a runtime exception in the control loop. That exception is how the bug announced itself. In a different implementation the overflow wraps and the toaster never pops. No exception at all. Still a bug.

These are obvious because everyone can see that what matters is the contract. The exception is only a vehicle for discovery.

Fifth, the correct taxonomy already exists and it does not match your story.

Industry standards separate three things. A fault is the cause in the code or design. An error is the incorrect internal state. A failure is the externally visible deviation. Exceptions are one mechanism for surfacing an error or failure. When an exception causes a failure relative to the spec, we have a bug. When an exception is expected and fully handled within the spec, we do not. This mapping is stable across languages in a way your concept versus data structure split is not.

Final point

Your thesis needs both of these to be true at once.

A) Exceptions mark fundamental flaws independent of intent. B) Bugs are only deviations from intent.

But we have shown counterexamples where intent flips the classification and where language choice flips the behavior. That means A and B cannot both stand. Once A falls, your whole distinction reduces to wordplay. Once B stands, the only consistent rule is this:

If an exception leads the program to violate its requirements, it is evidence of a bug. If it does not, it is routine control flow. In practice many exceptions are how bugs announce themselves. That is why production teams triage exception rates and not treatises on metaphysics.





> What you are calling fundamental is actually configurable convention.

Not within the topic's layer of abstraction. I can see you put a lot of thought into this, and if you were writing in a vacuum it might even be interesting, but discussion relies on context...

> If that ever happens in production, it is a bug.

Right. A bug, not an exception. Overloading the use of exception data structures and associated control flows does not imply that there is an exception in concept, just like using an error data structure to represent an email address[1] does not imply that you are dealing with an error in concept. It's just an email address.

> If it throws, the incident is a bug.

Right. A bug, not an exception. Again, just because you overloaded the use of a feature intended for dealing with exceptions for other purposes does not mean that you have an exception in concept. Just as an email address does not become a conceptual error just because you put it in an error data structure[1].

> If the runtime raises an exception and the loop dies, that exception is the manifestation of a bug.

Right. A bug, not an exception. I sense a recurring theme here. It is clear now that you've undeniably confused exceptions (data structure) with exceptions (concept). You obviously missed a lot of context so this may come as a surprise, but we were talking about the concept of programmer error. Data structures used in an implementation find no relevance here.

> In practice many exceptions are how bugs announce themselves.

As bugs and exceptions are different categories within the broader concept of programmer error, you could equally say "In practice many bugs are how bugs announce themselves". How, exactly, am I to grok that? I honestly have no idea what to make of that statement.

[1] let email = Error("[email protected]")


>Not within the topic’s layer of abstraction. I can see you put a lot of thought into this, and if you were writing in a vacuum it might even be interesting, but discussion relies on context…

You keep invoking “context” as a shield for avoiding substance. Context doesn’t change semantics. Arithmetic faults, null dereferences, and contract violations are not “configurable conventions” no matter how much pseudo-philosophical varnish you apply. Calling fundamental runtime behavior a “configurable convention” is like claiming gravity is optional if you talk about it at the right “layer of abstraction.” It sounds deep until anyone with an actual engineering background reads it.

>Right. A bug, not an exception. Overloading the use of exception data structures and associated control flows does not imply that there is an exception in concept, just like using an error data structure to represent an email address[1] does not imply that you are dealing with an error in concept. It’s just an email address.

Your “email analogy” is nonsense. The fact that something can be misused doesn’t invalidate its conceptual role. By that logic, if someone writes int banana = "hello", integers stop existing. Exceptions are not defined by their container type. They are defined by the runtime condition they represent. The fact that you have to keep insisting otherwise shows you have no grasp of the operational meaning of exceptions beyond the syntax of throw.

>Right. A bug, not an exception. Again, just because you overloaded the use of a feature intended for dealing with exceptions for other purposes does not mean that you have an exception in concept. Just as an email address does not become a conceptual error just because you put it in an error data structure[1].

Repeating the same broken analogy doesn’t make it coherent. You keep hammering at this contrived misuse like it proves anything. It doesn’t. It’s a straw man. Nobody is arguing that misusing the mechanism redefines the concept. You’ve constructed a toy example where you intentionally misuse a type and then triumphantly point to your own confusion as evidence. This is the intellectual equivalent of setting your keyboard on fire and declaring that typing is impossible.

>Right. A bug, not an exception. I sense a recurring theme here. It is clear now that you’ve undeniably confused exceptions (data structure) with exceptions (concept). You obviously missed a lot of context so this may come as a surprise, but we were talking about the concept of programmer error. Data structures used in an implementation find no relevance here.

You’re projecting your own confusion. You can’t even decide which layer you’re talking about. One moment you say exceptions are “data structures,” the next you say the data structure is irrelevant. You wave your hands at “concepts” but those concepts are precisely instantiated through those data structures. You don’t get to discard the implementation layer when it undermines your argument. Pretending the runtime’s behavior is irrelevant to the “concept of programmer error” is a convenient way to avoid admitting that bugs and exceptions are related manifestations of the same fault system. You’re not clarifying categories; you’re just renaming them until they stop overlapping.

>As bugs and exceptions are different categories within the broader concept of programmer error, you could equally say “In practice many bugs are how bugs announce themselves”. How, exactly, am I to grok that? I honestly have no idea what to make of that statement.

Of course you don’t. The problem isn’t the statement; it’s your refusal to recognize that categories can overlap without collapsing. Saying exceptions often announce bugs is perfectly coherent: bugs are latent causes, exceptions are how those causes surface at runtime. Your confusion stems from trying to turn mutually informative categories into mutually exclusive ones. It’s the same error a freshman makes when they insist that “rain isn’t weather because weather causes rain.”

[1] The Error("[email protected]") example doesn’t reveal deep insight; it reveals that you can misuse syntax. That’s not philosophy, it’s just bad code.


> They are defined by the runtime condition they represent.

Exactly. Exceptions represent conditions that violate the rules of the computing environment, while bugs represent conditions that violate "business" rules.

> Saying exceptions often announce bugs is perfectly coherent

Not really. If it were coherent we wouldn't be here. But perhaps what you are grasping to say is that it is possible that a bug could "corrupt" the computing environment, which could then also lead to an exception later on?

Allowing user input of "0" where the business rules say that "0" input is invalid would be considered a bug, and later when that 0 input is used as a divisor would see an exception (in an environment where divide by 0 is not permitted, for those who struggle). The exception in this case would likely reveal that there is also a bug in the user input.

But that does not imply that exceptions encompass bugs. Those are independent events, both wanting their own independent resolutions.


> But that does not imply that exceptions encompass bugs. Those are independent events, both wanting their own independent resolutions.

they do, unless you use exceptions for control flow


Neither exceptions, the concept, nor exceptions, the data structure, have anything to do with control flow. You could be thinking of exception handlers, which refers to a control flow mechanism, but if you were you'd be going completely off the rails.

Do you doubt you can use exceptions for control flow? Of course you need to combine with exception handlers.

It's the only use of exceptions not implying a bug


> Do you doubt you can use exceptions for control flow?

The same way you can use bugs for control flow, I suppose, given that bugs and exceptions are different categories within the same general idea of programmer mistakes. With bugs, of course, being mistakes around "business" rules, and exceptions being mistakes made around computing environment rules.

> Of course you need to combine with exception handlers.

How do you combine a programmer making a mistake with exception handlers? Exception handlers only exist inside programming languages. Are you under the impression that programmers also live inside programming languages? That's... interesting.


> With bugs, of course, being mistakes around "business" rules, and exceptions being mistakes made around computing environment rules.

For me, bugs are all mistakes which manifest themselves in software misbehaving. Maybe it surfaces by a program crash of an uncaught exception or an error message presented to the user, a program termination, a wrong result, ...

> How do you combine a programmer making a mistake with exception handlers?

I write a bug leading to an exception sometimes and catch the exception, then try the operation again, or show an error to the user


> For me, bugs are all mistakes which manifest themselves in software misbehaving.

And that's fine. It is not like there is some magical deity in the sky that creates and enforces the law of language. Words are just made up by humans on a whim. If I want to exert my own whim and call that "zigglefritz" instead, that works too.


>>They are defined by the runtime condition they represent.

>Exactly. Exceptions represent conditions that violate the rules of the computing environment, while bugs represent conditions that violate “business” rules.

You just moved the goalposts. In real systems the rules are one stack of contracts: language rules, library rules, service rules, business rules. A violation at any layer is a bug relative to that layer’s contract. Many exceptions are thrown for business rules as a matter of design. Examples:

   • ArgumentNullException when a domain service requires a nonempty customer id
   • IllegalStateException when a workflow step is called out of order
   • ValidationException on a failed business invariant
These are not violations of the CPU. They are domain failures surfaced as exceptions by choice. Your split collapses the second we leave toy examples.

>>Saying exceptions often announce bugs is perfectly coherent >Not really. If it were coherent we wouldn’t be here.

This is rhetoric, not a rebuttal. The production fact is simple. When an unhandled exception takes down a request and that outcome violates the service contract, that incident is triaged as a bug. If it is handled and stays within the contract, it is routine control flow. Teams do this every day without metaphysics.

>But perhaps what you are grasping to say is that it is possible that a bug could “corrupt” the computing environment, which could then also lead to an exception later on?

No need to reach for corruption. Ordinary causal chains are enough. Bad input passes validation when the spec says it must not. That is a bug. Later division by that input throws. The exception is the observable manifestation of the earlier bug. One cause. One effect. No magic. If your design instead clamps zero or returns a sentinel, then the exception would be the bug. The label follows the spec, not your taxonomy.

>Allowing user input of “0” where the business rules say that “0” input is invalid would be considered a bug, and later when that 0 input is used as a divisor would see an exception … The exception in this case would likely reveal that there is also a bug in the user input.

You have just restated that exceptions announce bugs. Your own example concedes the point you claimed was incoherent. The exception is how the system made the hidden violation visible. That is exactly what observability is for.

>But that does not imply that exceptions encompass bugs. Those are independent events, both wanting their own independent resolutions.

Independent events would mean no causal relation. Yet your own scenario shows a direct chain from the validation bug to the later exception. They are linked by cause and effect and are handled together in a single incident. Ops does not file two unrelated tickets and pretend the crash and the root cause are strangers.

The correct model is simple and general:

   • A spec defines allowed states at every layer.
   • A bug is entry into a disallowed state relative to that spec.
   • An exception is a mechanism that signals some disallowed states.
From this it follows:

   • Many bugs surface as exceptions.
   • Some exceptions are not bugs because the spec expects and handles them.
   • Some bugs do not raise exceptions because the language or code does not signal them.
Your attempt to split computing environment rules from business rules ignores that both are contracts, and violations of either are bugs. Your own examples demonstrate the causal link you say does not exist.

> You just moved the goalposts.

Nope. This carries the exact same semantic intent as my original comment. I've had to severely dumb down the phrasing over the course of discussion as it is clear you don't have a firm grasp on computing, and may continue to dumb it down even more if you continue to display that you don't understand, but there is nowhere for the goalposts to go. They were firmly set long before my time and cannot be moved.

> and violations of either are bugs.

They are both programmer error. "Bug" and "exception" are different labels we use to offer more refinement in exactly what kind of error was made. If I erroneously write code that operates on a null pointer, contrary to the rules of the computing environment, I created an exception. If I erroneously wrote code to paint a widget blue when the business people intended it to be red, I created a bug. While you may not understand the value in differentiating — to the user who only sees that the program isn't functioning correctly it is all the same, right? — programmers who work on projects in industry do, hence why they created different words for different conditions.

> the language or code does not signal them.

It seems you continue to confuse the exception data structure with exception as a categorical type of programmer error. The discussion is, was, and will only ever be about the later. There was no mention of programming languages at the onset of our discussion and turning us towards that is off-topic. You seem to be here in good faith, so let's keep it that way by staying true to the original topic.


> If I erroneously try to operate on a null pointer, I created an exception.

This is only true if some library/framework you use creates an exception for you.

Why do you operate on a null pointer in the first place? Well, you didn't because you painted something in the wrong color, but because you passed a null pointer to a piece of code, which should not have received a null pointer.


> This is only true if some library/framework you use creates an exception for you.

No. That's like saying you can't have errors unless you language/library/framework has an error datatype. Quite possibly the stupidest thing I've ever heard. A language doesn't need exception data structures or exception handlers for a programmer to violate a rule of the computing environment.


So the language/library/framework does not create an exception when operating on the null pointer, but instead it does not do anything (when it should change the color of a widget from blue to red).

Now you have a bug by operating on a null pointer, which supposedly is an exception, while exceptions cannot be bugs?


> So the language/library/framework does not create an exception when operating on the null pointer

It creates an exception in concept. It might not create an exception data structure, depending on the particulars of the language/library/framework. Which are you referring to when you say "exception" here?

It is a bit unfortunate that we've come to use "exception" to mean different things in different contexts. They are not dependent, though. Just as you can have an error in concept without an error data structure, you can have an exception in concept without an exception data structure.


> It creates an exception in concept. It might not create an exception data structure, depending on the language/library/framework. Which are you referring to when you say exception here?

it creates an exception (your concept), but no exception (data structure)


Right. Glad you understand now.



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: