What all your snide asides and unstated implications resolve to, is that the regex engine is incapable of safely comparing strings.

You skipped over the simpler (and verifiable, per my use of the word "parsing" in my first post in this thread) implication that the unreliable part is writing good regular expressions which are not fragile in the face of simple changes to unstructured data. (That's the same reason many people suggest not parsing HTML with regular expressions, for example.)

Whenever I write an exception system, I throw constants (or objects with a method returning such constants). Constants I export. So, if I were to change the value of a constant, the code would still run correctly (or at least, the programmer has to do some work to write code that doesn't run correctly on such a change). And if I were to change the name of a constant, there's a very high probability of the code no longer compiling. Then I can write code like:

Certainly. It's also possible for me to write a large Haskell program in one go which passes the type checker the first time, but I don't rely on that.

It's impossible to do plain string compare that isn't fragile in the face of simple changes.

Absolutely. Yet consider how classes and objects give you abstraction possibilities beyond which you can hide internal changes. That is, if you need to change your exception hierarchy in an incompatible way, you have the possibility of maintaining a compatibility layer between the old version (which can give a deprecation warning) and the new version.

Bare strings don't give you that possibility.

If you use—as I do—an exception system which uses roles to encode specific details about the type of exception then the only exact string comparison is to the name of the role and not any wording of the exception message. At some level in the system, something does have to compare a string to the name of a role yes, but that doesn't rely on any user having to craft the right regular expression which blends future proofing with accuracy.

Whenever I write an exception system, I throw constants....

Sure, I've seen that work well. Code which will only compile when it's correct is an advantage in these cases.

the unreliable part is writing good regular expressions which are not fragile in the face of simple changes to unstructured data

Ah! Now we're getting some where. I'm going to assume that you don;t consider yourself incapable of writing a good regex; which by implication suggests that you assume that wonderful catch-all, "other people", can't.

Of course, now we're well on the way to returning error numbers instead of strings. And then providing a function (class method) that converts them to an error text (when required). With the added benefit of making I8N simple.

Don't cover up simple design issues by layering heavy & complicated code over the top. Design a solution that addresses those issues at source. In this case, the source is the string form of the error returns, not the regexes the user needs to use to handle them.

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.

"Science is about questioning the status quo. Questioning authority".

In the absence of evidence, opinion is indistinguishable from prejudice.

When putting a smiley right before a closing parenthesis, do you:

Use two parentheses: (Like this: :) )
Use one parenthesis: (Like this: :)
Reverse direction of the smiley: (Like this: (: )
Use angle/square brackets instead of parentheses
Use C-style commenting to set the smiley off from the closing parenthesis
Make the smiley a dunce: (:>
I disapprove of emoticons
Other