Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:128275 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 1B6091A00BC for ; Mon, 28 Jul 2025 17:41:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1753724395; bh=iN4qXLM0q5URRs1AEy+qmf+zyidgSnu5EIFJEPq6peo=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=W+Udx62fVLhp4g/OqpeQexY3H/tru8zXPCmKpaXTNnUYfIsu2MOxPJHCSLu9rzTnP ZUjIPyY20sKPy1o1VvsWK6AY2nNKV3lu2bb6oRqBYZBSoYw45wH5IFfNYBPg6IDaD0 o9/Rh66Zj3vV5WscyKbptiW8jHZISgb8eaZxbmpNPP9quryUz5QmZ0Sedo97w7eYJ4 jUeBSFUR+Mq2Yl59siS72JAPxU+7vwICthPUqoPuXqXrEHPSzSsRTUruidAjx2mq6N 8s5cTsVcxfx4sAKb0aivQ2D1wZwHi27ip8z8OwKuPLhGE/uLLzi7wuMb+l0Y6NXYh4 oddKl2z5Qq22g== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id E4AA9180061 for ; Mon, 28 Jul 2025 17:39:54 +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=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, HTML_MESSAGE,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: Error (Cannot connect to unix socket '/var/run/clamav/clamd.ctl': connect: Connection refused) X-Envelope-From: Received: from mail-pf1-f181.google.com (mail-pf1-f181.google.com [209.85.210.181]) (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 ; Mon, 28 Jul 2025 17:39:54 +0000 (UTC) Received: by mail-pf1-f181.google.com with SMTP id d2e1a72fcca58-75ce8f8a3a1so2739456b3a.3 for ; Mon, 28 Jul 2025 10:41:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1753724496; x=1754329296; 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=/lxUjoyMhS7QcfFWa+ymRpaoj5MSl8Bt/6pu6g3x4YU=; b=FPn+tswAHISbJt4v0xZtmhrLPkdyphCtvJA0LboUaFEk+nDIptieTDM49p0jZfG8p9 m6XUhINzLIKMQD04+VDNxZqs/EGHkx6+TQcGsd8oLF4hGftWP+NeADrmK65sHHQGCAZm gAqsrTC9NiGiEisFYmkAD7kYlvrsASD+5Mq80+XJtDp1znKZ0o/BuQzgvk+8K+ZFrjPH WRJ7zE4+UWWhr3JKFGbNRKbddff2DNeZ6U7firQAvHCp4pAbSeg+Qt7TrUl3s6aKy8KT F9s5xsQx/v84DMqxT3ZjHAljLxzN4D//dbsodC+1DqJhusz4edzu19k1xlJTvrJq/+Tu IBzw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753724496; x=1754329296; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=/lxUjoyMhS7QcfFWa+ymRpaoj5MSl8Bt/6pu6g3x4YU=; b=KlBMeCjati4FlCtY5yjzqKEMMvvK6dGYW/Abjna43Ni7i3EscFXeHABgubEYIQC+QF dGhN7L5w4oXpzOVCMRoUEBqQF2lN9WsJgTT1EKvCfU/GMwvR8F9gqzs56WR2lStJpVoQ kl8Evd2ZdC0AldqpJ+Fj7X7IJBFdNMWOCxZ0pibGVcDf0TzDO0Yryvqx5sMBvpulICeY esBMSvUvNVJEKZlxcMoEvlXg6vPLCuK6j7LD1GXfPI8TAV/4DoSJJ4qz7ApNKEWlngHk JjUwtnN64h4vtZkvq29dT3oQXHKes3YuJ1kJThrBsDO7a/XBl3d574aocJ7Y7ytx4p3h gf9Q== X-Gm-Message-State: AOJu0YyyklKcvTEbMq9RhXuTKbPgckORtz5dwEktC3HqFG4SEHHV1oFZ zdzRf5W/ZgepstTq1VHQbqTQ070rK9awN409ELF67/hI3BtU5ujG/dN5qkfL8/JBnxSbCDy65rt E4UpBC1cRBVqNBBumUdOzJKAMKhTrKCwTX04kF0A= X-Gm-Gg: ASbGncuAowZTJYkuvXk0OBtrPGA1o/TZnEYpUHIAqLBC/3n8RWjkzYHa4arVmhuAYV1 webP6YNpDAr2qRmGBwI1DV7mWIn3mWcvRrp3J1PnqbNIqit0JPFytcdiTsf4UdBQia6cwgVWphZ aoZXZ0FfFA7mRauuaak3HGrNII5yggLHtFR7tRthsSi+XSk88b8Ikb+pzkGTfZNVf/3uPaagSFf 8QJx4g7 X-Google-Smtp-Source: AGHT+IEuKxBVLF1iEMtRE2irGoTRo/soADnmmmte1NTTutwDCVdasrHFY+AnaT8Loo8xng7g/zSJB/B3o+iC7CALZMA= X-Received: by 2002:a05:6a20:2451:b0:21a:bc07:b42c with SMTP id adf61e73a8af0-23d70188994mr20119823637.30.1753724496389; Mon, 28 Jul 2025 10:41:36 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 References: <73a35675dff31a1eaf76b67af567194e@bastelstu.be> In-Reply-To: <73a35675dff31a1eaf76b67af567194e@bastelstu.be> Date: Mon, 28 Jul 2025 20:41:25 +0300 X-Gm-Features: Ac12FXz-d8lMcOVuVr6JGkk6pYP3JLetNrMtR6yVjuoWUhyhN8_b6hbAdmnqw2Y Message-ID: Subject: Re: [PHP-DEV] [DISCUSSION] User-land Throwable To: =?UTF-8?Q?Tim_D=C3=BCsterhus?= Cc: PHP internals Content-Type: multipart/alternative; boundary="000000000000a42e8e063b00cd40" From: xepozzd@gmail.com (Dmitry Derepko) --000000000000a42e8e063b00cd40 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Mon, Jul 28, 2025 at 1:17=E2=80=AFPM Tim D=C3=BCsterhus wrote: > I'm afraid I don't quite understand what actual goal you intend to solve > with the proposal. The description of your use case is very abstract, > can you provide a real-world example of a use-case you want to enable? > > Best regards > Tim D=C3=BCsterhus > Sure. Imagine 2 PHP services: - backend monolith - mailer At some condition the "backend" makes an HTTP request to the "mailer". The "mailer" answer with corresponding HTTP status, RPC body or in another way. When something goes wrong mailer responses with: - status - error message - error trace On the "backend" side we may inform the user that HTTP request failed: - check for response status - create an exception -- with the error message in the "message" prop -- and with the error trace in a custom prop, e.g. $externalTrace Our exception renderer is quite powerful and renders all the chained errors one by one: ``` Error "$e->getMessage()" occurred on the line "$e->getLine()"... - During handling another exception: "$e->getPrevious()->getMessage()" on the line "$e->getPrevious()->getLine()"... -- During handling another exception: "$e->getPrevious()->getPrevious()->getMessage()" and so on. Unfortunately, dumping all the properties of an exception is not possible: there may be cycled references or just not readable bytes. So, I should create a workaround (as many in this thread): - Handle a particular class separately, reading a custom property, converting the traces to some PHP-like form - Or create an interface for such exceptions - Or append the traces to the message string - Or just dump the traces to the log and make users to open logs Instead, users may - Construct an exception from the external structure: message and trace - Raise an exception like "HttpClientException" and passing the exception from the previous point as a "previous" exception After that an error renderer may render the traces as a regular chain of exceptions, even if there are traces that are not related to the current project. Moreover, traces may come from another language like Go/Python/Java/etc. They still may be accessible and useful to the end user. Of course I'm not talking about production systems and showing traces to everyone. As usual, they should be accessible only for developers. This is my real case of using Temporal with a PHP server. When something fails, you can access the traces from a custom exception property / get looong "message". Here some code snippets: function req($url, $params) { $resp =3D $client->get($url, $params); if ($resp->status > 300) { $parsed =3D json_decode($resp->getBody()); $prev =3D new Exception(message: $parsed['message'], trace: $parsed['trace']); // or create a separate MyException and set trace there, or externally with setTrace() throw new ClientHttpException("HTTP request to the $url was failed", previous: $prev); // chain traces to the 3rd party } } {message: "...", trace: [...]} isn't contracted by PHP, a library should parse it itself. ------ Moving further, there is an era of long-running apps. Coroutines also come soon. We may choose between classic exceptions with the "stack" trace and modified exceptions with a custom-edited trace: prepend/append traces with the coroutine-scope name or clean application bootstrap trace. I'm not sure about mutating a complete trace of an exception, but still as a case of usage. --=20 Best regards, Dmitrii Derepko. @xepozz --000000000000a42e8e063b00cd40 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
On Mon, Jul 28, 2025 at 1:17=E2=80=AFPM T= im D=C3=BCsterhus <tim@bastelstu.be<= /a>> wrote:


Imagine 2 PHP services:

- backend monolit= h
- mailer

At some condition the "b= ackend" makes an HTTP request to the "mailer".
The= "mailer" answer with corresponding HTTP status, RPC body or in a= nother way.

When something goes wrong mailer respo= nses with:
- status
- error message
- error t= race

On the "backend" side we may inform= the user that HTTP request failed:
- check for response status
- create an exception
-- with the error message in the &= quot;message" prop
-- and with the error trace in a custom p= rop, e.g. $externalTrace

Our exception renderer is= quite powerful=C2=A0and renders all the chained errors one by one:
```
Error "$e->getMessage()" occurred=C2=A0on the= line "$e->getLine()"...
- During handling another e= xception: "$e->getPrevious()->getMessage()" on the line &qu= ot;$e->getPrevious()->getLine()"...
-- During handling= another exception: "$e->getPrevious()->getPrevious()->getMes= sage()"

and so on.

U= nfortunately, dumping all the properties of an exception is not possible: t= here may be cycled references or just not readable bytes.=C2=A0
S= o, I should create a workaround (as many in this thread):
- Handl= e a particular class separately, reading a custom property, converting the = traces to some PHP-like form
- Or create an interface for such ex= ceptions
- Or append the traces to the message string
-= Or just dump the traces to the log and make users to open logs
<= br>
Instead, users may
-=C2=A0Construct an exception fr= om the external structure: message and trace
- Raise an exception= like "HttpClientException" and passing the exception from the pr= evious point as a "previous" exception

A= fter that an error renderer may render the traces as a regular chain of exc= eptions, even if there are traces that are not related to the current proje= ct.

Moreover, traces may come from another languag= e like Go/Python/Java/etc. They still may be accessible and useful to the e= nd user.

Of course I'm not talking about produ= ction systems and showing traces to everyone. As usual, they should be acce= ssible only for developers.

This is my real case o= f using Temporal with a PHP server.=C2=A0
When something fails, y= ou can access the traces from a custom exception property / get looong &quo= t;message".

Here some code snippets:

=
}

{message: "...", trace: [...]} is= n't contracted by PHP, a library should parse it itself.

=
------


Moving further, t= here is an era of long-running apps. Coroutines also come soon.
W= e may choose between classic exceptions with the "stack" trace an= d modified exceptions with a custom-edited trace: prepend/append traces wit= h the coroutine-scope name or clean application bootstrap trace.
= I'm not sure about mutating a complete trace of an exception, but still= as a case of usage.

--
--000000000000a42e8e063b00cd40--