Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:83108 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 19949 invoked from network); 18 Feb 2015 19:30:20 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 18 Feb 2015 19:30:20 -0000 Authentication-Results: pb1.pair.com smtp.mail=danack@basereality.com; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=danack@basereality.com; sender-id=unknown Received-SPF: error (pb1.pair.com: domain basereality.com from 209.85.160.179 cause and error) X-PHP-List-Original-Sender: danack@basereality.com X-Host-Fingerprint: 209.85.160.179 mail-yk0-f179.google.com Received: from [209.85.160.179] ([209.85.160.179:43524] helo=mail-yk0-f179.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id E0/A5-25021-A48E4E45 for ; Wed, 18 Feb 2015 14:30:19 -0500 Received: by mail-yk0-f179.google.com with SMTP id 9so1862087ykp.10 for ; Wed, 18 Feb 2015 11:30:16 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=+7vxmMTg8IhUyJTHXBT5p95GnLQXpzgij/ji8/nnk1o=; b=Zmr3RSPQgpQuROK/ZspE60WFYMxIFJrDJd5+dsOZp2jc1YHkblo6eZmMWSLWdwZaH2 lvaJAB3QgWx2wlzmxWcQVUOAynITPD3wzuC4u5Ku3CbmIAJoklMmgTb7qhTNwfDuYt7H TxqHvldgEpzb8bs16OW0m030b06ZgavGz+urls/bC9FmxeNHzXe9tAM+hUoaFWbTHY1B ZnYQEomWMwB7aal9CtI9YBIUQ2Yw07tpDuUZLy/EAc0TZZ21wZo00+IFLOa0doP+XS/A G6/z7mjsvpg+FEUatnXNmi0g7v+BPohE8sNdG4B+NMdS0y1TW5QZjiaWm0SshtCDNZ6P lZYw== X-Gm-Message-State: ALoCoQmGEIwcHR/E7EQzpwTrl4D0p0lVx3Y7o8iRKkntMfGD2fD64bzH7hxB18mfoy5GAciICXW7 MIME-Version: 1.0 X-Received: by 10.170.90.70 with SMTP id h67mr1022820yka.46.1424287815967; Wed, 18 Feb 2015 11:30:15 -0800 (PST) Received: by 10.170.71.86 with HTTP; Wed, 18 Feb 2015 11:30:15 -0800 (PST) X-Originating-IP: [89.240.52.213] In-Reply-To: References: Date: Wed, 18 Feb 2015 19:30:15 +0000 Message-ID: To: Nikita Popov Cc: PHP internals Content-Type: text/plain; charset=UTF-8 Subject: Re: [PHP-DEV] Re: [RFC] Exceptions in the engine From: danack@basereality.com (Dan Ackroyd) On 13 February 2015 at 23:25, Nikita Popov wrote: > Subclassing: Should there be more specific subclasses of EngineException > for particular errors? It's not obvious that any subclasses would be useful. However using the code to specify the exact type of error, rather than having to inspect the message would be good. > Should EngineException inherit from Exception (and as such be > subject to catch(Exception)) or should we introduce some kind > of special super-class that is not caught by default Even ignoring the BC problem with having EngineExceptions extending Exception, I think the EngineException needs to be in a different hierarchy to Exception to be able to write reasonable code in the future Without having EngineException in a separate hierarchy of exceptions, the code below will catch exceptions where the data is 'ok' but there was a problem with the code, and continue to process items. This is almost certainly not the correct behaviour when an EngineException has been encountered. interface Service { function foo($item); } function processData(array $itemsToProcess, service $service) { foreach ($itemsToProcess as $item) { try { $service->foo($item); } // Because $service can throw an Exception that is specific to the // implementation we have to catch \Exception, unless we are going // to list all possible implementation specific exception types here. // That would be a subtle case of strong coupling, and when a new // implementation is made the new exception type would need to // be added here. catch(\Exception $e) { // item was not processable but PHP engine is OK. $item->markAsErrored(); //Go on to process the next item } } } To avoid having EngineExceptions in a separate hierarchy, this function could be converted to: function processData(array $itemsToProcess, service $service) { foreach ($itemsToProcess as $item) { try { $service->foo($item); } catch(\EngineException $ee) { //PHP engine is not stable - lets get out of here. throw $ee; //or throw new ProcessException($ee) } catch(\Exception $e) { $item->markAsErrored(); } } } However that is bad as i)it's boiler plate to do the correct behaviour ii) you have to remember to do that everywhere. Having to remember to do the correct thing, is going to lead to people forgetting. It will still be necessary to catch all types of Exception in a single catch block i.e. at the top level of a script to prevent exceptions being shown to the end user. This could be made easier by having a common super class for Exception and EngineException. However having one try block that is required to have multiple catch statements to catch all different types of exception is not that much of a burden: try { runApp(); } catch(EngineException $e) { handleException($ee); } catch(Exception $e) { handleException($e); } As that would be the only place it would be required to catch both types. TL:DR EngineException needs to not extend Exception, whether we need a super class is not as clear. cheers Dan