Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:67383 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 61840 invoked from network); 10 May 2013 02:21:06 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 10 May 2013 02:21:06 -0000 Authentication-Results: pb1.pair.com smtp.mail=rasmus@mindplay.dk; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=rasmus@mindplay.dk; sender-id=unknown Received-SPF: error (pb1.pair.com: domain mindplay.dk from 209.85.128.171 cause and error) X-PHP-List-Original-Sender: rasmus@mindplay.dk X-Host-Fingerprint: 209.85.128.171 mail-ve0-f171.google.com Received: from [209.85.128.171] ([209.85.128.171:43637] helo=mail-ve0-f171.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 8E/11-53423-E895C815 for ; Thu, 09 May 2013 22:21:05 -0400 Received: by mail-ve0-f171.google.com with SMTP id m1so308078ves.16 for ; Thu, 09 May 2013 19:21:00 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:x-received:sender:in-reply-to:references:date :x-google-sender-auth:message-id:subject:from:to:cc:content-type :x-gm-message-state; bh=ktTLuHb9WB6W7dRuTEd9B7MmIKyWWO6SIcDVx/OyKFY=; b=QEeZVEB1yZwIGdU6xzy1sijO3kyaRzkyFCmQbzlUWhX3bO15F7lZZHf21w3ZJr7DH8 jBekkioooqBkx+GPaW+snthram9D902rovIvMGgH2kuodHzNeSPf1sJ1S0Fjc6KNZXNt katyl6/AEYOF+A0sBAWH75eXO8bcD8daCFeXwaOXRcITvlsFe93KZbyQkq5MV+7ynQj2 jaxKcxbdtD2m5Lc7Fu7tkncBfMrYzeOsVqdsmVdMfUa+0ABorgS6MprhVu954nRWxkRm RUaCvmAkSvfIVYWBlSHJn/gcHA27z5wsBXKcsHWYshB+ppqvjjO4OoNJ7SJhy5bizLqR 358w== MIME-Version: 1.0 X-Received: by 10.58.226.163 with SMTP id rt3mr9650848vec.55.1368152459562; Thu, 09 May 2013 19:20:59 -0700 (PDT) Sender: rasmus@mindplay.dk Received: by 10.58.28.134 with HTTP; Thu, 9 May 2013 19:20:59 -0700 (PDT) In-Reply-To: References: Date: Thu, 9 May 2013 22:20:59 -0400 X-Google-Sender-Auth: aMQrEzsccWSyLxBW4mukn1-9N1U Message-ID: To: Etienne Kneuss Cc: Rasmus Schultz , PHP internals Content-Type: multipart/alternative; boundary=047d7bd6aed459eb4804dc53d18c X-Gm-Message-State: ALoCoQnyUMzLq5J82hDksea8+sCEUBFeJQxyK54zcNpZ429CYwdX2JeWfxPhF78V88AjSAlHlYWp Subject: Re: [PHP-DEV] exceptions during __toString() From: me@rasmus-schultz.com (Rasmus Schultz) --047d7bd6aed459eb4804dc53d18c Content-Type: text/plain; charset=ISO-8859-1 I've heard the technical explanation before, and while it probably doesn't make sense to go through all that effort to fix this... well... take this example: class Foo { public function __toString() { try { return $this->bar(); } catch (Exception $e) { trigger_error(E_USER_ERROR, $e->__toString()); } } protected function bar() { throw new RuntimeException('ouch'); } } $test = new Foo(); echo $test; This is OK in theory, but just rather odd, and won't work with many frameworks and error-handlers, if errors are caught and thrown as the built-in ErrorException - the natural expectation would be that this should be enough: public function __toString() { return $this->bar(); } What if that basically did the same thing? An implicit try/catch inside __toString() as above, but instead of passing the error to trigger_error() and triggering the error-handler, pass it to the built-in exception-handler, or whatever was configured with set_exception_handler() That way, we would at least get a meaningful error message, even if it's still not possible for exceptions to bubble up through implicit calls made to __toString() internally. Wouldn't that at least suck less? :-) On Thu, May 9, 2013 at 6:50 PM, Etienne Kneuss wrote: > > > > On Fri, May 10, 2013 at 12:00 AM, Rasmus Schultz wrote: > >> I just ran into this issue again: >> >> >> http://stackoverflow.com/questions/2429642/why-its-impossible-to-throw-exception-from-tostring >> >> Instead of throwing some nonsense "you're not allowed to throw from here" >> error-message, how about actually unwinding the stack and passing the >> exception to the global exception-handler? >> >> I understand there's a technical limitation making it difficult/impossible >> to handle exceptions during __toString() - and it looks like you can still >> try {...} catch (Exception $e) in __toString() just fine, but then what? >> You have the exception, but you have no way to pass it to the standard >> global exception-handler. >> >> If the script has to terminate either way, why not terminate the same way >> an unhandled exception would normally cause the script to terminate? >> >> E.g. output the actual error-message, or pass it to whatever was >> registered >> with register_exception_handler() so it can be output or handled in the >> usual way? >> > > > The reason is that toString can be triggered from a lot of internal > places. > If an exception is thrown and caught within toString, it's not a problem. > The problem is if the exception escapes toString, because it thus means > that the code invoking toString must be interrupted. > > We in fact have no guarantee that all those internal places will work > consistently/correctly in the presence of an exception, and if the engine > will remain in a state that allows executing code afterward. > Not executing code means we need to bypass error handlers as well. > > Handling an exception from internal code is a "manual" procedure, and code > written that relies on conversions to strings may not have been written > with support for exceptions in mind. > > I guess the alternative approach is to allow exceptions, review the code > (i.e. a lot of work), and eventually fix reports as they come in. > > Best, > > -- > Etienne Kneuss > --047d7bd6aed459eb4804dc53d18c--