On Tue, Feb 6, 2024, at 7:56 PM, Григорий Senior PHP / Разработчик Web wrote: > Thanks Larry, I will read both articles next weekend. > > Am not even talking about changing `throw` to `raise`. > > Am talking only about: > - production ready code > - that should be able to refactor with error collectors (that was not > implemented years ago) > - without touching return types > - without touching input arguments of existing code > - without possible code fall after throw exception: you have to try/catch > all places you use that function (sometimes you predict possible error, and > yes, write return class/enum to extend/refactor it later) > (and yes, if old code did not support returning null/null-object before - > you have to refactor return types then) > > While working with queues you have a list of tasks > - then you reduce it to smaller with reducer (unique/filter/merge) > - then do some queries > - then walk initial data using reduced results: copying reports to save > errors/warnings to each task separately > > It cannot be solved with exceptions. In addition, large arrays throw > exceptions that cause timeloss. It's definitely not a tool for. > Also your method could return many errors (today - only one > error/exception), and you need to write a second method, then call the > second method, then debug the second method. > > So what's in rest? Arrays collection of warnings and errors. Changing > return types or passing second-return by reference. > > [ Enum case ~ DTO output ] covers newly written code. Old code is > uncovered. You have to rewrite a full tree, that's why some trick is > necessary. > > I did it my way with an error bag stack. I enable it inside the function or > in place I call the function. I want to share this experience, and imagined > it would be better for all users. It could be done without 2 classes, 10 > functions and work with push/pop/current (closer to ob_start/ob_get_clean > story). > I guess it could be implemented if `raise` world will put any data to the > current error bag in the stack. Exactly if the current error bag is present > (declared manually like you can declare() strict types or ticks for some > scope). > > I agree that there's more mandatory problems to solve that I didn't even > know about. > I tried to talk about error handling with a few developers, all of them > recommend: > 1. Use exceptions, don't make anything fresh > 2. Do validation at the script start to reduce the count of errors later > > I've just encountered cases where bugs come from within - once you > integrate a really bad external system with its own checks, which are > described in hundreds of documents, I'm sure you'll encounter new bugs once > the "working" code is released to production. And then you will need to > quickly and easily reorganize it. > > And you can't. > And you will be sad. > And, "PHP moves differently" is a completely wrong principle, I believe in > "watching for". I think there's a subtle but important difference here between what you're describing as the problem and what you implied the solution was (which I then ran with).
What you're talking about is trying to change the error handling model of existing code without changing function signatures. There are only two possible ways to do that, both of them bad: Unchecked exceptions and globals. What I described, based on the syntax you offered, is checked exceptions, which necessarily means changing the function signature. Error handling is part of the contract of a function. If its error handling changes, it *should* have a signature change to indicate that. (That unchecked exceptions do not do that is the problem with unchecked exceptions.) So if "no changes to existing code" is the goal, checked exceptions as I describe them are not the answer you are looking for. It seems from your latest message that you're describing more a generalized version of `json_last_error()` and similar functions. The problem there is that such an API design is generally considered very poor practice outside of C, because it's all necessarily based on globals and "hope you remembered to check the thing that no one told you to check and is not even slightly obvious to check". That is not something I would want better support for in the language at all. There's probably cleaner ways to emulate it in user-space, but that is for a particular application to sort out. There's definitely cleaner monadic solutions (which I've written before and are quite neat) using a writer/logger monad, but that again doesn't meet your "don't change existing code" requirement. I don't think anything the language can do will meet that requirement and be a good design. --Larry Garfield -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php