Hi,

On Thu, Feb 26, 2026 at 7:56 AM Nicolas Grekas <[email protected]>
wrote:

>
>
> Le mer. 25 févr. 2026 à 20:16, Jakub Zelenka <[email protected]> a écrit :
>
>> Hi,
>>
>> On Wed, Feb 25, 2026 at 7:11 PM Nicolas Grekas <
>> [email protected]> wrote:
>>
>>> Hi Jakub,
>>>
>>> I would like to introduce a new stream error handling RFC that is part
>>>>> of my stream evolution work (PHP Foundation project funded by Sovereign
>>>>> Tech Fund) :
>>>>>
>>>>> https://wiki.php.net/rfc/stream_errors
>>>>>
>>>>>
>>>> As there has not been much discussion and keeping the patch up to date
>>>> is a slight pain, I plan to open voting on Friday (27/02/26) evening or
>>>> Saturday (28/02/26) morning unless some changes are required ofc.
>>>>
>>>
>>> Thanks for the reminder! I discussed this with others and we raised the
>>> following points:
>>>
>>> 1. StreamErrorCode::None: do we need it?
>>>
>>> Having an enum case representing "no error" feels a bit off to me. If an
>>> API needs to express the absence of an error, would,'t StreamErrorCode|null
>>> be more idiomatic? StreamErrorCode::None seems like a nullable value
>>> disguised as an enum case, and it means callers always have to guard
>>> against it, which somewhat defeats the purpose of using an enum. Am I
>>> missing a use case where ::None is genuinely needed?
>>>
>>
>> Yeah this wouldn't make sense as enum but it would probs still make sense
>> to keep it if it changes to constant
>>
>>
>>> 2. StreamError::$next — is the naming intentional?
>>>
>>> Since stream_get_last_error() returns the most recent error and the
>>> chain travels backwards through time, $next seems to point to the previous
>>> error chronologically. Would something like $previous (echoing
>>> Throwable::getPrevious()) work better, or is the current naming deliberate?
>>>
>>>
>> I will double check it but getPrevious() might make more sense.
>>
>>
>>> 3. Should StreamErrorCode really be an enum?
>>>
>>> The RFC lists in its "Future Scope" section: "Extension-specific error
>>> ranges - Reserved ranges for extensions to define custom error codes."
>>>
>>> This gave us pause. Enums in PHP are intentionally a closed, finite
>>> type: their value is precisely that "invalid states become
>>> unrepresentable." If extensions can define custom error codes at runtime,
>>> the set of possible values would depend on which extensions are installed,
>>> and the type would no longer be truly enumerable.
>>> Larry touches on this exact tension in this post: when the value space
>>> needs to be open or user-extensible, an enum is the wrong tool.
>>> https://www.garfieldtech.com/blog/on-the-use-of-enums#open-type
>>>
>>> I'd also expect the built-in list of codes to keep growing over time as
>>> more wrappers and edge cases are covered; which is another hint the domain
>>> may not be fixed.
>>>
>>> Would a set of integer constants (possibly grouped in a class or
>>> interface) be appropriate? It would be more honest about the open-ended
>>> nature of the value space while still allowing meaningful comparisons,
>>> without creating false expectations of exhaustiveness.
>>>
>>
>> Ok if enum should be closed, then I agree that this should be changed
>> because there might be new errors. Larry suggested it before but I didn't
>> see any mention that enum should stay unchanged in future versions. I will
>> change it to StreamError class constants and add static helper
>> classification functions there.
>>
>>
>>>
>>> 4. Using stream_context_set_default to change error_mode looks hazardous
>>>
>>> The RFC includes an example where stream_context_set_default is used to
>>> set error_mode to StreamErrorMode::Exception globally. I'm worried about
>>> the ecosystem impact here: if any library or application bootstrap does use
>>> this, then existing packages using the common
>>> @file_get_contents('maybe_existing_file') idiom could e.g. suddenly throw
>>> uncaught exceptions, breaking behavior their authors had deliberately
>>> chosen. This feels like a significant compatibility hazard for code that
>>> doesn't control its full execution environment.
>>>
>>> Would it be worth restricting error_mode (and possibly the other new
>>> options) so that they can only be set via per-call contexts, not via
>>> stream_context_set_default?
>>>
>>>
>> Hmm that's how stream context works and it would seem quite hacky to add
>> restriction on global context (we would basically need to add some
>> validation when global context is set). What's worse is that it would
>> prevent to change error handling for cases where it is not possible to set
>> context (fsockopen and various other cases). This is actually in some way
>> already possible by throwing from the stream notifications (limited to http
>> wrapper though) but I can see how it could have bigger impact here. I'm
>> afraid the libraries will have to deal with that which should eventually
>> lead to a better code.
>>
>
>
> Thanks for acknowledging the first items, I'm looking forward to the
> update.
>
> About this last one, I need to insist: that global behavior is going to be
> a nightmare. Everytime someone proposes to add a new ini setting to
> configure some global behavior, we say so. The reasons are exactly the
> same. Existing code will just have to be rewritten, which might lead to
> better code but also to high friction. Exactly like a BC break - it'll be
> one actually.
>
> About adding validation to stream_context_set_default, that looks like a
> non issue to me.
> About fsockopen et al, that's a very good reason to add a context
> argument. Without that, properly using those function would mean changing
> the global stat all the time. Better not plan for this.
>
>
Ok I think you are right that the BC impact would be just too big so I will
add that validation.

Kind regards,

Jakub

Reply via email to