Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:130528 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 DAB801A00BC for ; Thu, 2 Apr 2026 09:17:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1775121483; bh=wn4RDAUIM8N0f5cxofXNNiFl6X9roZs7Mx6c5SNVfDA=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=KIs9cYXuMiIb27jAqAislFCcwD0CA/HgZRPJa5GDT8PAmu6gCGuazWTSVsXY+ZReu JiVHn8Jtm10UWr5Ki/IIsV6DWh+NaQGRX3gp7WURyX9eu1ZuldM1UiStaDc4JHj8dG 9fUagU8eN8spezRRD3Yw/b/FhDXhQ9r5KqHFgK0xc8nprr7CgUr6WsJxYc0EIPK732 BFTvWyekXyWbl5vo5dNNW0t7WqICKiT3S5tXjhmO6rSwG8b0XnP0zdjCJrXVGW5efD vAXDa05iek41womJ8kGNfWpUpcEI2ODYPxCfn1hjaNEH1eaYIYaw77kyjbzZzy+kvd KjjughSH7CLEQ== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id ABF31180087 for ; Thu, 2 Apr 2026 09:18:02 +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,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL, SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from mail-ot1-f48.google.com (mail-ot1-f48.google.com [209.85.210.48]) (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 ; Thu, 2 Apr 2026 09:18:02 +0000 (UTC) Received: by mail-ot1-f48.google.com with SMTP id 46e09a7af769-7d7c77fd31cso621595a34.3 for ; Thu, 02 Apr 2026 02:17:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1775121477; cv=none; d=google.com; s=arc-20240605; b=SoBJoOsDCCvnmYRTCVmWFgWV2QJUX0vHO3LX2haa+0UIHsYf5SgBOQJZDg0NlEgYty 95v9C8UrJyL7l2coxWUq1+yy5cmm5iDwWzfgAiGmzHxt/nvM5sMT9xQzk/GamsgLDcE7 Q/TYRLtZlX8dotBEGbA99N4eLH4dchqntA5+z+wLoBr9LUm5TSff3VtZTKxq2NLdd+NX OCXisJCZXGN875Qe4R7KJ6DsBiebnteK+3G9PZRnv1M6d0SEJGtQaTmdhVIn+A4EazVI g5QH8GhXKCec2PA/1kgCKitKm+btYEvZ8MaXSwjCh21MXWrN+H2q6MMWgwIM5oGBsO0H rnQQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=FRuKJM+JHqNWRaEmrNDFZqhoMAXyCiEu2fT/T0Vybp4=; fh=TZSkz6T1qvbRTfq1USLyxoniJBEFuJjoYmJkaFLpsPg=; b=APTu5cAKiUUHgDfclkiWfTTalX/jJqc/9crx2w4x2upI2fmPxg7Y0I6uQkDpaBVvaZ xH/vk1CzniER6sCQwdPSQoLPEFxr4MKG52tCirYT4/sisZWxTR7pFTD2xmG9gNlCr+Xg 1oJr6qnNegzk6yVxHqfjY7paUTthlpRbQ7uhNBHUSWy0bW+7T7pEZjkA6qoC1n3IkWp3 +Jo9qtar0SZu76r2gHqlUns+S7kGXkfqVNldQ0SAgkqpbG6NaVzulLxcVMcP4sMkBECP uol1Dea8QnLmTj8rzLzmTBTa0ibaUApbEKJ972XWA9jZKxvr9g3AHzdpDmo5clx+i6SD Z7Kw==; 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=20251104; t=1775121477; x=1775726277; darn=lists.php.net; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=FRuKJM+JHqNWRaEmrNDFZqhoMAXyCiEu2fT/T0Vybp4=; b=kWpa5KUxUqZU2fQ2wVZEfDvWhHca/LOJCCQQ+0Uf+rQMmYENQKIVd8ai8Z+gQENRPa tSQjHQrIn1roYGT9kC0up6fvb0kbmLJFI+hLF3lLtQUWTGAt4dKGc+DLKo9tWmXB1EAj JfiUlXS/R/AEUXLYNYPHLNVkvShwuNGpGY2cyFbKR4sAr27/J8eiXzBxqdupML5RRL9N XB7yPKAu69T1kiO51fx+kk/LzmxWofHhrY1LI0s5iPbbzdsiyyXFkok17kjZXfiIuFNq xROB4chkHhbP/rjtwPvmu0kJ+DMvUSOzM1eUflwVvEquRncrlwpEiau7i4M8zxrOveRa yF9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775121477; x=1775726277; h=content-transfer-encoding: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=FRuKJM+JHqNWRaEmrNDFZqhoMAXyCiEu2fT/T0Vybp4=; b=IJw1XDTgK3v03tvbrpCPZ2IHWFPHpLszgRBHoBsuheSQzBAwT929smiPuNWU1IHo2+ LM00H0kpCVu9CgC6SjhTUAuEAmpVzQ9bQTqzs4XEh+aGpOmPAfcKYxlblX/wzwgSFzG5 sP8VNfUZTwmNe5GgJ6lVEnUGkdlE1/Gp1J/amW5oqpiUu7Hcb+BTuxbmIVSplKKbAr6S kuFjqmnJR7Y+HhpNsImz7IHPisMPKhFmBsZ40oSJKU2Vau8ufpagTvayeWJz1kKJSAZG gMJEFy0rmCdD0r//IVVJ/xtXZorjHU8bXt4dIpxORbPeyqdVfvnnVfcGB/CgQU7LVFAY odZQ== X-Forwarded-Encrypted: i=1; AJvYcCXTVeUbpgB0Hz2KDE3iKiLpWNkhlmeUUNtv0vgfkiMaoARnqQu+rgLyb61CCsbq6wsAp+WF7PdAE4E=@lists.php.net X-Gm-Message-State: AOJu0YxQKiU/dC0XBBNQj9uFicQ7zDjC/rGsaXhzaMG/TLSuOS9gOLDB POUCIusrhLW5AHUVfQjYBQVDaTaNsGy4lMXEwEo4HuTg8q0OTwUMrtSMTYGrOWXz8hb+LHC2tT/ h3cWpYVGeTRSJ/+TMEV3rTs+U64G3VH4= X-Gm-Gg: ATEYQzygIrhQcchBwrEjpIwKs8GdWQquucnwnzoPTPO0TExFn/Qt3D2C8KHl/ccnF0l oprc0sJ6je45FBYCtpKuFwrwLTJMBmEYJHlDN/zPMdQtmuGG9xNpsSCGIaO6xyZ4vmqpMNuiCbP S+qoKU+gnzSguqCFhjCSQHZo7UrZCAHGnxHkm0luw4lnxDtp0qno9GIlZ6+/YiwYlGCDehaC0Jg YEjwPuNKVQoDutFQj69SxEKAzgr4aR7u43EBCYdLJsrnltYp19q822Ns+HniRO5Dkg93lj5ueFm VPrZoJE+64JAEIoYMw8Q0a21I0kXFyhwcAXmCXa0PjckWy/Q78gx X-Received: by 2002:a05:6820:c83:b0:67d:e552:922e with SMTP id 006d021491bc7-67fabc98021mr3871399eaf.35.1775121476789; Thu, 02 Apr 2026 02:17:56 -0700 (PDT) Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 References: <1597c99a0ad7dc1e55a40f952d7536c5@bastelstu.be> In-Reply-To: <1597c99a0ad7dc1e55a40f952d7536c5@bastelstu.be> Date: Thu, 2 Apr 2026 16:17:45 +0700 X-Gm-Features: AQROBzB0CiCHNvdkPQ94WVBsWflIblUFZExoq5CgXfp5Plj_d5eEIgsKl6iFUBc Message-ID: Subject: Re: [PHP-DEV] Re: [RFC] Stream Error Handling Improvements To: =?UTF-8?Q?Tim_D=C3=BCsterhus?= Cc: Jakub Zelenka , Nicolas Grekas , PHP internals list Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable From: pierre.php@gmail.com (Pierre Joye) Hi Tim, Jakub, On Tue, Mar 31, 2026 at 5:52=E2=80=AFPM Tim D=C3=BCsterhus 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 :). --=20 Pierre