On Mon, Oct 17, 2022, at 12:33 PM, Tim Düsterhus wrote: >>> Okay, now the Exception message changed. Personally I do not consider >>> this a BC break: I believe Exception messages are meant for human >>> consumption, not for programs. Otherwise fixing a typo in the message >>> would be a BC break. If the code wants to learn about the cause, it >>> should either use the '$code' or different types of Exception should be >>> thrown to clarify the cause by entering a different catch() block. >>> >> >> Yes, the specific error message should be part of the BC promise. This >> allows building test suites that can assert the message in a stable way. > > I'm not talking about test suites here. I believe makes sense to verify > the error message to ensure a specific error message is emitted to the > human observer in the error log. > > I was talking about code that does something like this, which I consider > to be inherently unsafe: > > try { … } > catch (SomeException $e) { > if ($e->getMessage() === 'Foobar') doSomething(); > else doSomethingElse(); > } > > As a library author I want to be able to provide the best possible > Exception message to ease debugging for the user. This is not possible > if I am locked into a bad choice forever.
Just to be clear, such code is sometimes necessary. If the exception doesn't include sufficient information as dedicated properties, parsing out the string becomes the only option. I've had to do this myself. In 100% of cases, without exception (no pun intended), that's because the code that throws the exception is bad and wrong and should be fixed. But such code absolutely exists in the wild, including in php-src. I recently needed to sscanf() and then explode the message of \ArgumentCountError as that was the only way I could find to get the class/method names out of it. I died inside a little. So yes, such code is inherently unsafe, but is sadly not as uncommon as it should be. All that said, I agree that we have not and should not treat error message strings as part of the API guarantee. If anything, maybe that will help incentivize people to stop writing bad (unparsable) exceptions. Which I think gets at the crux of the issue here, and what is often the issue in BC discussions. PHP does not, and has never, guaranteed full BC for all code. It has tried very hard to maintain BC for "well-behaved code." Well-behaved code can generally update to a new version, even a new major, very easily with minimal work. Any deprecations are alerted at least a year in advance, sometimes several, and usually have easy-to-automate transitions that tools like Rector can implement. (The discussion about deprecations being "too noisy" in some tooling is another matter that has been hashed out before, so I won't belabor it here.) Code that is following common best-practices rarely has an issue. The problem is that "well-behaved" is not well-defined. Is relying on an error message string well-behaved? I'd argue no, but as noted above sometimes there's no better option. Others may disagree. Is relying on the exact exception class thrown well-behaved? Well... sometimes. Is relying on an error condition being swallowed rather than turning into an exception well-behaved? I could argue either way here, honestly. Is code relying on undefined variables silently becoming null well-behaved? Absolutely not, and hasn't been for a decade, but it wasn't until PHP 8.0 that the language called people out for it by default, so many projects had a lot of catch up to do. (Eg, I did that catch up for TYPO3.) I don't know that we can make a clear definition of "well-behaved" that everyone could agree on. It would be nice, but it's a very squishy topic. But it may be prudent, when not tied down to this specific RFC, to have a broader discussion about better codifying (meaning, writing down) what we consider a BC break and what we don't, what some heuristics are for "well-behaved," and so on. That could help avoid, or at least shorten, a lot of discussions in the future. --Larry Garfield -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php