Ola,

Als ik op php.net kijk bij de omschrijving van InvalidArgumentException dan staat er:

"Exception thrown if an argument is not of the expected type."

Nu vraag ik me af of je een InvalidArgumentException ook kunt gooien op het moment dat er een key/id wordt aangeroepen die niet bestaat. In principe zou je dan kunnen zeggen dat het argument ook ongeldig is. Je hebt immers iets aangeroepen dat niet bestaat.

Nu zie ik dat PHP ook een OutOfBoundsException kent:

"Exception thrown if a value is not a valid key. This represents errors that cannot be detected at compile time."

Als ik het goed begrijp zou dit de exception zijn die je moet gooien als een key niet bestaat?

Ik vind het een lastig onderscheid eerlijk gezegd. Waarom niet uitsluitend de InvalidArgumentException gebruiken? Hoe doen jullie dat?
Je kunt zoeken naar een key die niet bestaat. Denk bijvoorbeeld aan een record-ID voor een klantnummer, een artikelnummer, enzovoort. Dat is dus niet per se een exception, maar vaak een normale en te verwachten toestand van een systeem.
Dat klopt Ward, maar er zijn ook situaties als deze denkbaar:

<?php

$foo = $config->get('foo');

?>
Hier ga ik er vanuit dat er een 'foo' key bestaat, maar blijkbaar heb ik me vergist, dus moet er een exception worden gegooid. Ik vraag me af welke exception ik dan moet gooien. Ik dacht dus om een InvalidArgumentException te gooien, omdat ik blijkbaar een argument he opgegeven van een ID/key die niet bestaat. Maar ik zou graag weten of dit een juiste keuze is.
"This represents errors that cannot be detected at compile time."

<?php

function get($index, array $array) {

if ($index < 0) {
throw new OutOfBoundsException('index cannot be lower then zero');
}
if ($index >= count($array)) {
throw new OutOfBoundsException('index has to be lower then the number of elements');
}

return array_values($array)[$index];
}

get((int) $_GET['index'], [42]);
get((int) $_GET['index'], [1, 1, 2, 3, 5, 8, 13]);

?>
Hoi Dos,

Ik lees wat er staat, maar mijn technische kennis is nog niet zover dat ik het helemaal begrijp.

Wat wordt er bedoeld met "errors that cannot be detected at compile time"?

En als ik nu een niet bestaande key ingeef? Bijv. ik moet de key "Dos" hebben, maar ik typ in plaats daarvan per ongeluk "Dox". $dos = $config->get('Dox'). Die key bestaat niet. Welke exception moet er dan worden gegooid?
OutOfBoundsException is prima aangezien de compiler niet weet of 'Dox' op het moment dat die regel uitgevoerd wordt een valide key is. 'key' is wel toegestaan om als key te gebruiken, dus het is geen invalide argument wat de methode betreft.
Oké, ik snap wat je bedoelt Dos. Ik vind OutOfBoundsException alleen helemaal geen prettige naam (voor mezelf). Ik vind 'm te onduidelijk en te lastig om te onthouden.

Misschien kan ik er beter UnknownIdException van maken. Wat vind je daarvan?

Overigens vraag ik me iets af... dat geldt eigenlijk voor alle exceptions. Leg je de "schuld" neer bij de programmeur, of leg je de "schuld" neer bij de server?

Klinkt misschien een beetje vaag, dus ik zal uitleggen wat ik bedoel.

Stel je roept een bestand aan en dat bestand bestaat niet, zeg je dan in je exception message:

A: ("schuld" bij programmeur) je hebt een niet bestaand bestand "foo.php" aangeroepen

OF

B: ("schuld" bij server) kan het bestand "foo.php" niet vinden
Wat maakt het nou uit hoe je het zegt. Of je nu de schuld bij de programmeur of de server legt. Het gaat er om dat de boodschap duidelijk is.

Zelfde met excepties. OutOfBoundsException zegt dat er iets buiten de "grenzen" is gekomen. Dat duidt dus eerder op iets als een array. Je hebt keys van 1 tm/ 10 maar key 23 wordt opgevraagd. Dan stap je dus butien die "bounds" of "boundary" en gooi je die exceptie.

Als je voor dit verhaal niet goed weet welke je moet gebruiken van de bestaande, maak je zelf een Exception class aan die "ConfigurationPropertyNotFoundException" oid. Zolang het maar een indicatie geeft van wat er fout gaat is het goed. Zou hier ook echt niet te lang bij stil staan.
Okeej... ik sta er ook niet te lang bij stil. Maar je hebt soms van die dingen waar je pas achteraf achter komt dat je het beter op een andere/handigere manier had kunnen aanpakken. Vandaar dat ik graag wat extra visies ontvang.

Je kunt inderdaad zoiets gebruiken als ConfigurationPropertyNotFoundException, maar je moet er ook voor waken dat je dan weer niet 10 verschillende variaties daarop krijgt... ProductPropertyNotFoundException, UserPropertyNotFoundException enz. Daarom wil ik een zo algemene, maar toch zo specifiek als mogelijke, naam gebruiken voor overeenkomstige situaties.
D Vivendi op 11/03/2014 14:38:12

Wat maakt het nou uit hoe je het zegt. Of je nu de schuld bij de programmeur of de server legt. Het gaat er om dat de boodschap duidelijk is.

Het maakt niet veel maar wel iets uit. De LogicException en subklassen zoals de InvalidArgumentException tikken de developer bij tests op de vingers en mogen in productie niet meer voorkomen:

“Exception that represents error in the program logic. This kind of exceptions should directly lead to a fix in your code.”
Ward van der Put op 11/03/2014 15:07:19

Het maakt niet veel maar wel iets uit. De LogicException en subklassen zoals de InvalidArgumentException tikken de developer bij tests op de vingers en mogen in productie niet meer voorkomen:

“Exception that represents error in the program logic. This kind of exceptions should directly lead to a fix in your code.”


Dan heb je het over de exception zelf. Ik had het alleen over het bericht zelf wat je bij de exceptie toont. Of je nu "foo.php bestaat niet" of "foo.php niet gevonden" zegt, dat maakt dan in weze niet echt veel verschil. Komt op het zelfde neer.

Reageren