Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:92446 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 30584 invoked from network); 19 Apr 2016 09:56:14 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 19 Apr 2016 09:56:14 -0000 Authentication-Results: pb1.pair.com smtp.mail=zeev@zend.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=zeev@zend.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain zend.com designates 157.56.110.107 as permitted sender) X-PHP-List-Original-Sender: zeev@zend.com X-Host-Fingerprint: 157.56.110.107 mail-bn1bn0107.outbound.protection.outlook.com Received: from [157.56.110.107] ([157.56.110.107:57499] helo=na01-bn1-obe.outbound.protection.outlook.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id D3/01-24636-DB006175 for ; Tue, 19 Apr 2016 05:56:14 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=RWSoftware.onmicrosoft.com; s=selector1-zend-com; h=From:To:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=DPNwvypcyYogJbzZvPyKNgvdR0iiJacK24cnjNQJu5U=; b=0n6NHFTDQzgmJHdEbQdB77Y9w4rxg6uGD6h56CVOMYNTR0bowavri53HK6SHUi6vUo1aupBW6tjIssJBMBzzigtZdASLXQze13xYlwS2ObxLlrWGC5/FuAd3lamSC6J8isuSaQoCrjRyRZueVgIYTviJ3JFDIxZAj5Uyn8jwntM= Received: from BY2PR02MB298.namprd02.prod.outlook.com (10.141.140.21) by BY2PR02MB300.namprd02.prod.outlook.com (10.141.140.26) with Microsoft SMTP Server (TLS) id 15.1.466.19; Tue, 19 Apr 2016 09:56:09 +0000 Received: from BY2PR02MB298.namprd02.prod.outlook.com ([10.141.140.21]) by BY2PR02MB298.namprd02.prod.outlook.com ([10.141.140.21]) with mapi id 15.01.0466.022; Tue, 19 Apr 2016 09:56:10 +0000 To: Derick Rethans , Marco Pivetta CC: PHP internals Thread-Topic: [PHP-DEV] [VOTE] Catching Multiple Exception Types Thread-Index: AQHRmMlr+2y+N0CM4kmdEfDlLDJpZJ+OyqWAgADzowCAABsIgIABF91w Date: Tue, 19 Apr 2016 09:56:09 +0000 Message-ID: References: In-Reply-To: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: php.net; dkim=none (message not signed) header.d=none;php.net; dmarc=none action=none header.from=zend.com; x-originating-ip: [212.199.177.67] x-ms-office365-filtering-correlation-id: 02de733e-b495-4b55-7165-08d36838d5a9 x-microsoft-exchange-diagnostics: 1;BY2PR02MB300;5:XPVhIo6E0pvK0LQLTZU9MlN/qmfThyb+SnBLsmhpp9BkDD4R6F5qhB1fMX8GmdkAu3iYr3a9btOJJTyQ/i3NDy0VtgAFL2rr/JPhjkKnQGKAKqqTCEOK90FVvawnyQFqrneN7pZSHKWOVq666WjarNPKRmghGRg6TX+xWp1P3ERi+Ke6V3Fu+B3hDEmmJ0mJ;24:K6cHew7BgDiHZhC2tO0C9yLbjef+yelVK48CsRVdkdsx959m7Pzrf71WoWr/VpRKh/v7dvh3aDGrxqaliVm23cMz6WoGY4WixPL4qkN3NJU=;7:k62qnZlz8dhzSGH51lDvYrlk/DelyCND0VL5wfSsTA2bQTzxXdZF6FynqMDavrbOrYLe8b1h+XpEgBFrWZH07njUd7nrH8ggtHfi+BJRJHxM/9C6tQy1ffm6Kdt7fdIASvTNOCZDdoI0Gjn7jQWhnBntIzxnVQmefPUXncRMDOOWQkG9hD2ZT57ymK17Az221FESpF9Tk3YW3Fb174DhKClqJCiA2DhymO2UgvhIG6k= x-microsoft-antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BY2PR02MB300; x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:; x-exchange-antispam-report-cfa-test: BCL:0;PCL:0;RULEID:(9101521026)(601004)(2401047)(5005006)(8121501046)(10201501046)(3002001);SRVR:BY2PR02MB300;BCL:0;PCL:0;RULEID:;SRVR:BY2PR02MB300; x-forefront-prvs: 0917DFAC67 x-forefront-antispam-report: SFV:NSPM;SFS:(10019020)(6009001)(24454002)(13464003)(377454003)(2906002)(586003)(122556002)(3846002)(102836003)(6116002)(5004730100002)(19580405001)(19580395003)(5001770100001)(189998001)(5002640100001)(2950100001)(10400500002)(4326007)(76576001)(5008740100001)(1096002)(1220700001)(3280700002)(99286002)(9686002)(92566002)(3660700001)(2900100001)(106116001)(81166005)(77096005)(86362001)(93886004)(33656002)(50986999)(74316001)(76176999)(54356999)(87936001)(5003600100002)(66066001);DIR:OUT;SFP:1102;SCL:1;SRVR:BY2PR02MB300;H:BY2PR02MB298.namprd02.prod.outlook.com;FPR:;SPF:None;MLV:sfv;LANG:en; spamdiagnosticoutput: 1:23 spamdiagnosticmetadata: NSPM Content-Type: text/plain; charset="iso-8859-2" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: zend.com X-MS-Exchange-CrossTenant-originalarrivaltime: 19 Apr 2016 09:56:09.9293 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 32210298-c08b-4829-8097-6b12c025a892 X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY2PR02MB300 Subject: RE: [PHP-DEV] [VOTE] Catching Multiple Exception Types From: zeev@zend.com (Zeev Suraski) > -----Original Message----- > From: Derick Rethans [mailto:derick@php.net] > Sent: Monday, April 18, 2016 6:18 PM > To: Marco Pivetta > Cc: Dan Ackroyd ; Bronis=B3aw Bia=B3ek > ; PHP internals > Subject: Re: [PHP-DEV] [VOTE] Catching Multiple Exception Types >=20 > On Mon, 18 Apr 2016, Marco Pivetta wrote: >=20 > > Heya, > > > > I voted "NO" due to previous discussion. TL;DR: this is FAR off the > > 80/20 use-case for a language syntax change. >=20 > I'm with you on this one. >=20 > > C&P from my answer elsewhere: > > > > The following typical example is something REALLY rare, and requiring > > a parser change for it seems excessive: > > > > try { > > // ... > > } catch (InvalidArgumentException $e) { > > // same handling > > } catch (PDOException $e) { > > // same handling > > } catch (BadMethodCallException $e) { > > // same handling > > } > > > > These 3 exceptions usually result in separate handling anyway. If same > > handling is needed, you can as usual extract a private method (if you > > are in a class) and deal with it there: > > > > try { > > // ... > > } catch (InvalidArgumentException $e) { > > $this->sameHandling($e); > > } catch (PDOException $e) { > > $this->sameHandling($e); > > } catch (BadMethodCallException $e) { > > $this->sameHandling($e); > > } > > > > private function sameHandling(Throwable $caught) > > { > > // same handling > > } >=20 > Even this is a scary way to do it. As you don't know which exception clas= s you > have, how would you know how to handle each separately. In reality, you often don't truly 'handle' exceptions at all. Different ex= ception types are very often just a slightly fancier and easier way to retu= rn errors, and it's actually very common and perfectly reasonable to handle= groups of exceptions in an identical way. It's also extremely common to s= ee exception handlers that don't pay any attention to the exception object = itself. In fact, glancing through the Zend Framework 2 codebase and the Dr= upal 8 codebase, it seems that the exception object is rarely ever used.=20 In Drupal 8, many catch blocks simply resort to return FALSE or TRUE. For = example: try { return $router->match($path); } catch (ResourceNotFoundException $e) { return FALSE; } catch (ParamNotConvertedException $e) { return FALSE; } catch (AccessDeniedHttpException $e) { return FALSE; } catch (MethodNotAllowedException $e) { return FALSE; } } Note that this is in fact different from catch (Exception $e), and I'm gues= sing the author intentionally did not want to catch an exception the type o= f which she/he weren't expecting to get - and instead, have it propagate up= wards. With this RFC approved, it would become: try { return $router->match($path); } catch (ResourceNotFoundException|ParamNotConvertedException|AccessDenie= dHttpException|MethodNotAllowedException $e) { return FALSE; } Which is much, much nicer and readable. And I found this in the ZF2 codeba= se: } catch (DiRuntimeException $e) { if ($methodRequirementType & self::RESOLVE_STRICT) { //finally ( be aware to do at the end of flow) array_pop($this->currentDependencies); if (isset($alias)) { array_pop($this->currentAliasDependenencies); } // if this item was marked strict, // plus it cannot be resolve, and no value exist, = bail out throw new Exception\MissingPropertyException( sprintf( 'Missing %s for parameter ' . $name . ' fo= r ' . $class . '::' . $method, (($value[0] =3D=3D=3D null) ? 'value' : 'i= nstance/object') ), $e->getCode(), $e ); } else { //finally ( be aware to do at the end of flow) array_pop($this->currentDependencies); if (isset($alias)) { array_pop($this->currentAliasDependenencies); } return false; } } catch (ServiceManagerException $e) { // Zend\ServiceManager\Exception\ServiceNotCreatedExce= ption if ($methodRequirementType & self::RESOLVE_STRICT) { //finally ( be aware to do at the end of flow) array_pop($this->currentDependencies); if (isset($alias)) { array_pop($this->currentAliasDependenencies); } // if this item was marked strict, // plus it cannot be resolve, and no value exist, = bail out throw new Exception\MissingPropertyException( sprintf( 'Missing %s for parameter ' . $name . ' fo= r ' . $class . '::' . $method, (($value[0] =3D=3D=3D null) ? 'value' : 'i= nstance/object') ), $e->getCode(), $e ); } else { //finally ( be aware to do at the end of flow) array_pop($this->currentDependencies); if (isset($alias)) { array_pop($this->currentAliasDependenencies); } return false; } } To save everyone some time, the two code blocks for the two exception types= are completely identical. I'm not sure why it wasn't function()alized, bu= t regardless, it's another case where the new proposed feature would make p= erfect sense. I think saying that identical handling for multiple exception types is bad = or is grounds for an urgent code review is fairly disconnected from reality= in many if not most cases. Zeev