Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:130171 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by lists.php.net (Postfix) with ESMTPS id 9DC261A00BC for ; Wed, 25 Feb 2026 18:11:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1772043096; bh=axGmZZtmUOUT9DuDl6vJJW5LLaKWh7fh2H9ae/YErhs=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=HDWeGWiPuEoktfeLZWav6W2IBNJAdhlFB+57oRpX7lU45NjEkKzaOssn2dBy+4rOU NVWENgTaN4QZGgj1ELqyk+CNV0ndnOxAaWSqXk8RHKJum/Ix+q+gz63cQ61jBimNCI OBsnTv0jAvJExoMyBmoGaeGBCX4GJv4xnCqFtUQmzXYEfyHm0FkXWVZ3Cyb8ckcTFa qfYUTFvzMkr0vDQStCfgmptQSr9bNgqHaMGqkjkNknednzxlVqh+GkxsCXYlIkN+iL Ha9Yx7T/jfFCEyiufvJP3i4SLgHsrf2NfHAIAMtQOdlzQn8qvbEsID/Xyg6HeQxpOE YZP6hthLQ+JWQ== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id A15F118007E for ; Wed, 25 Feb 2026 18:11:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=0.6 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_50, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS, FREEMAIL_FROM,HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2, SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from mail-qv1-f52.google.com (mail-qv1-f52.google.com [209.85.219.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Wed, 25 Feb 2026 18:11:31 +0000 (UTC) Received: by mail-qv1-f52.google.com with SMTP id 6a1803df08f44-896ff127650so115772306d6.3 for ; Wed, 25 Feb 2026 10:11:26 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1772043085; cv=none; d=google.com; s=arc-20240605; b=ZpyooJkB7dQM8w72wJvc/duwnrT1+aodvQC4rrCD/5DrfRSXoixUPAyI3SRRbuqjUG Xy2nMviNOnMXk4CcaA0ARxqZzPDk4yyPsbzkuahujkG0iasZBdwb8FAUYR9ktgXtB64i ux5XfoY/SwQC3POVkISDYqbdY9TvcX4l+vAkSjtaHFmbQgc2aCuBRfcMqk0K3koXj6N6 QBDp9BEYf97+LzZyBPLOLgzu0s1f2emjFKc8yS+09gwym1crtS1PkrE69VRfj8hSMVIS qfaUK84Uzy5V08y8Y1cYXgbpRUI73gZKZaLCnMl+kX82vLHdHPbz7LKQbOu/HQInlLjI r9Dw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:dkim-signature; bh=axGmZZtmUOUT9DuDl6vJJW5LLaKWh7fh2H9ae/YErhs=; fh=e1jcWte0mPTSZlyXl/HLkSXX/3nWNC/faQfpUh1NqBQ=; b=RYDy/DP3ipkags2gUcDYsY4Wbm0NSaxm+t8+FMAO/bIdfkUFoOqsmGeCtzTK4o+eqi XDpj7BJxhEH/g4EAqa74I146TD+Ttts1AT3xi1ZiEEj3xnidDD1nOC1+ZrjMQWyrqFy5 LnAjhoyemLMO86kUioJHE7GOli+vmUw/s8blcUHHMSBIlGZnBFlW0qbpqWR/2PYM7wzN 8Kro8ZwcOOFcxjEYtpW3Xlqkg0kk4a37mhJ8rtzXvORJHnPpJHOke0QUdqyONhn/Z+Ti wYUipTg7WufNA0RY9IhOjnoE9n2SRVCMndEoxR5JPTQ6+kiuTgo6IrK2YX7XB9A+rN7x blHw==; darn=lists.php.net ARC-Authentication-Results: i=1; mx.google.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1772043085; x=1772647885; darn=lists.php.net; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=axGmZZtmUOUT9DuDl6vJJW5LLaKWh7fh2H9ae/YErhs=; b=TytDqYp6Lrvq4Tyt+ivOuHtQSoeHcYiBuNDsKxUHOgThtQPmkrg5DjJb1o15MFtk1y ZgNIAZ/gFVrqAUhRGhUPj1slBjtHtNHOAX4m60J0jWEOyOJLSqci7GdkHjnQa2b1XQov qcDbqQIeJHyLXdb9BBUib+t6Arm8J6KW6ryAFvJRJkv6eRWqaWSdqtWm1Hu5OlKI9DTv 0oCgnMSA4M6GXxQR1TkroaQZANPaclEcKksLQm/YoPjSmm40JrKHsP3LzHfdkvDFxo5M 1ELyVOyQWc7oKcbB1F+WxbZSVIXfCQiqa6hzuprCYZXJomyORm5e/ZHFy5yJ5TgyhFUH KfyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772043085; x=1772647885; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=axGmZZtmUOUT9DuDl6vJJW5LLaKWh7fh2H9ae/YErhs=; b=gjS+sOk6jL9rfJZLC/w5BSuv15KqroJqPuTL9eBomDjKvgvNGUDxPe8O4+V1Ym6QY9 v3z2hIY6GKPNSI6mgXXyrwjJVpG142GKnfPhGadZart0gtAkgSodOHdz99kkcSwKyk23 S5Rg3imAP90eYDYEwumbxylTJ2v5L6J8sFOlE4+ppzVynHr3vKpvzSF98bSqLuakG2Df /XgkMsMZrDnfkvO43YpXKBgNvPuh8+mMt7xSLXsG34EKvjpUezMt3ibETKs1a6Mh+x/H qU1k5WrjgYup2vPpHwQco5W2OZRsJvKlwBWecORDT/YX7DEypx+zLrPWIzYNBYCvPTLE KQ7Q== X-Gm-Message-State: AOJu0Yyps8nhk8WUTdzAAEPVAFsmYY3FRxzMs0omD/c/DukffZ40fGXT AXTnjUO2dmWizxOqSSLBIdjilCaIr0L0L4WpbOlKpMprCZdvlryGNWueBpKl4Fjlf+TEhENFvXc P/gxleJ4Z8KwJjqU8BLobJ2e0SKFrQWBn7geOt9w= X-Gm-Gg: ATEYQzwmYBFFggNiGBqzq0ym36ekmKiSH/VOu7pJlT2pg9RXG0hO+6ckPHKbcTYe+uX anMj4B8x94ZOmgbZKslIUKe9Ot6XpB15QnV96R3jki8ZdZ8/5ZN5vThu0ZgVteZCkAi/17c2gOA MRbxi/ZbE1Uj11AGv95wenURmS8pAqLJF98x4y7OuupVkeLY8k/LiaLnYSiVoyws8Ys/kMUwPgc 64TC40YGb13Zr11VsxhbiCqTUgrLCmlociZivFWkgPLKhq7EJnorNl61xGTz+kb0+bh5J18m5kx jnplH0Xjdw/NWFMQwJJZW4XgSOOsESMx4PvLYA3LoH7bNgNKtL3zuiPznnDkXR06hcNPWcJVbKC QkQ/8SIDbQ7aZwLXk7YgKMuBo3wY= X-Received: by 2002:a05:6214:f0b:b0:894:7d25:d6ba with SMTP id 6a1803df08f44-899c13b95a4mr20293266d6.6.1772043085368; Wed, 25 Feb 2026 10:11:25 -0800 (PST) Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 References: In-Reply-To: Date: Wed, 25 Feb 2026 19:11:14 +0100 X-Gm-Features: AaiRm51f-K1wcJCW-SVtyWH6suI0mweNBhsjQAweVzHj8sMl7M820Co40HU0kBk Message-ID: Subject: Re: [PHP-DEV] Re: [RFC] Stream Error Handling Improvements To: Jakub Zelenka Cc: PHP internals list Content-Type: multipart/alternative; boundary="000000000000a1524f064ba9eeeb" From: nicolas.grekas+php@gmail.com (Nicolas Grekas) --000000000000a1524f064ba9eeeb Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable 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 Tec= h >> 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? 2. StreamError::$next =E2=80=94 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? 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. 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? Thanks for working on this, we definitely need this! Cheers, Nicolas --000000000000a1524f064ba9eeeb Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi Jakub,


1. StreamErrorCo= de::None: do we need it?

Having an enum case representing "no e= rror" feels a bit off to me. If an API needs to express the absence of= an error, would,'t StreamErrorCode|null be more idiomatic? StreamError= Code::None seems like a nullable value disguised as an enum case, and it me= ans callers always have to guard against it, which somewhat defeats the pur= pose of using an enum. Am I missing a use case where ::None is genuinely ne= eded?

2. StreamError::$next =E2=80=94 is the naming intentional?
=
Since stream_get_last_error() returns the most recent error and the cha= in travels backwards through time, $next seems to point to the previous err= or chronologically. Would something like $previous (echoing Throwable::getP= revious()) work better, or is the current naming deliberate?

3. Shou= ld StreamErrorCode really be an enum?

The RFC lists in its "Fut= ure Scope" section: "Extension-specific error ranges - Reserved r= anges for extensions to define custom error codes."

This gave u= s pause. Enums in PHP are intentionally a closed, finite type: their value = is precisely that "invalid states become unrepresentable." If ext= ensions can define custom error codes at runtime, the set of possible value= s would depend on which extensions are installed, and the type would no lon= ger be truly enumerable.
Larry touches on this exact tension in this pos= t: 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-enu= ms#open-type

I'd also expect the built-in list of codes to k= eep 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 co= nstants (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 exh= austiveness.

4. Using stream_context_set_default to change error_mod= e looks hazardous

The RFC includes an example where stream_context_s= et_default is used to set error_mode to StreamErrorMode::Exception globally= . I'm worried about the ecosystem impact here: if any library or applic= ation bootstrap does use this,=C2=A0then existing packages using the common= @file_get_contents('maybe_existing_file') idiom could e.g. suddenl= y throw uncaught exceptions, breaking behavior their authors had deliberate= ly chosen. This feels like a significant compatibility hazard for code that= doesn't control its full execution environment.

Would it be wor= th 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?=

Thanks for working on this, we definitely need this!
=
Cheers,
Nicolas
--000000000000a1524f064ba9eeeb--