Re: Re: [RFC] Stream Error Handling Improvements

From: Date: Thu, 02 Apr 2026 09:17:45 +0000
Subject: Re: Re: [RFC] Stream Error Handling Improvements
References: 1 2 3 4 5 6 7  Groups: php.internals 
Request: Send a blank email to internals+get-130528@lists.php.net to get a copy of this message
Hi Tim, Jakub, On Tue, Mar 31, 2026 at 5:52 PM Tim Düsterhus <tim@bastelstu.be> wrote: > > Hi > > Am 2026-03-29 20:25, schrieb Jakub Zelenka: > >> For the naming of stream_get_last_error(): Within PHP > >> we have both > >> X_get_last_error() and > >> X_last_error(). The latter seems to be more > >> common and also what I would prefer here, because the > >> stream_get_ > >> prefix sounds to me like we would get something from a stream, but the > >> returned value is not related to a specific stream, but rather a > >> global. > >> > >> > > Good point, I changed it but because it now returns array (no linked > > list), > > it's called stream_last_errors(). I also added stream_clear_errors for > > explicit clearing which might be useful in some situations. > > That both makes sense to me. > > > The RFC and the implementation is updated so please take a look! > ... > 3. For "StreamErrorCode::is*()" > > Can error codes fall into multiple categories or is it always a single > one? If it's guaranteed to be a single category, then perhaps a > ->getErrorCategory() method returning a > StreamErrorCodeCategory enum > makes more sense and allow for simpler / more efficient code when folks > are interested in checking for multiple different categories. Instead of > $code->isNetworkError() || $code->isFileSystemError() > they can do > `\in_array($code->getErrorCategory(), > [StreamErrorCodeCategory::NetworkError, > StreamErrorCodeCategory::FileSystemError], true) or use a > match()` These points actually are on the spot about what I've been trying to raise earlier in this thread, or they demonstrate it nicely. Suggesting a getErrorCategory() method or a StreamErrorCodeCategory enum to make category checks cleaner. That's a reasonable API improvement, in the context of what the RFC proposes in the current state. But it also highlights the underlying design issue: we're building a parallel categorization system on top of error codes, when the type system already provides exactly this, through exception subclasses, for free. That reminds a bit of the early OO's time in php when all we did was to wrap the legacy procedural implementation in dumb OO wrapper, saving, if lucky, user's keystrokes. That's not even the case here. The point is that a stream operation can produce errors of different categories and therefore the exception "cannot be reasonably categorised": this is how exceptions have always worked. One throws the primary exception, the one that caused the operation to fail, and chain additional context via $previous or attach it as metadata. The caller catches what they care about: catch (StreamNetworkException $e) {...} The exception type answers "what do I do about this?" The error chain answers exactly what happens, where in detail. These are different questions for different uses, and conflating them is what leads to the current design where it catches a flat StreamException and then has to inspect its contents to find out what kind of failure it was. getErrorCategory() suggestion would give us match($e->getErrors()[0]->getErrorCategory()) { ... } inside a catch block. That's essentially reimplementing what catch (StreamNetworkException $e) already does, except the type system can't help, static analysis can't reason about it, and it can't compose it with other exception handling in a codebase. The current RFC introduces exception syntax without exception semantics. The isFileSystemError(), isNetworkError() methods, and now potentially getErrorCategory(). are workarounds for the absence of a typed hierarchy, not features we should need in the 1st place. Since StreamException does not exist in any current PHP version, there is zero BC cost to making it a proper base class now. It takes more effort to design such additions correctly, however it would be a significant improvement in the long run for php's stream, beyond a current internal refactoring and long due cleaning :). -- Pierre

« previous php.internals (#130528) next »