[oop] InvalidArgumentException
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.
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.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?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]);
?>
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]);
?>
Gewijzigd op 10/03/2014 23:14:54 door Dos Moonen
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.
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
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.
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.”
“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.
-compile time krijg je als je een rood streepje onder je code ziet wanneer je aan het coderen bent.
-run time krijg je wanneer je de applicatie runt en een fout naar je hoofd gegooid krijgt.
Overigens is het leuk en aardig dat je OutOfBoundsException geen leuke benaming vind maar let wel op.. dit is een algemene exception die bij veel programmeurs bekend is. wanneer jij allemaal custom errors terug gooit dan is het voor jou opvolger heel moeilijk om te achterhalen wat die fout is of waarom die error.
Als ik een OutOfBoundsException krijg dan weet ik dat het te maken heeft met het feit dat ik een array key aanroep die niet bestaat.
stel ik krijg UnknownIdException dan denk ik bij mezelf ohh nee weer een creatieve developer die zijn eigen errors namaakt.
In principe kan je de aangeleverde foutmeldingen gebruiken met een eigen stukje tekst voor de duidelijkheid zoals in Dos' voorbeeldje.
>> compile time krijg je als je een rood streepje onder je code ziet wanneer je aan het coderen bent.
Bedoel je daarmee bijv. dat ik een ; vergeet? Dat soort fouten kun je toch niet opvangen?
>> run time krijg je wanneer je de applicatie runt en een fout naar je hoofd gegooid krijgt.
Maar dan lijkt het me dat alle exceptions run time exceptions zijn. Of zeg ik nu iets geks?
Anders gezegd, je krijgt een compiler fout op het moment dat je een fout hebt in je code (bv haakje vergeten etc, etc.)
Runtime errors krijg je wanneer je bv een object vanuit je db probeert te halen maar dat dan de db niets terug geeft.
Kun je een compiler fout dan vergelijken met een spelfout?
Compiler errors ontstaan doordat je je ergens een ;, { etc. vergeet.
Maar tenzij je bootstrap en autoloaders geen fouten bevatten heb je in principe wel een runtime error.
Alle exceptions zijn runtime, alleen binnen runtime heb je ook weer verschil: Errors kunnen afhangen van de code alleen (LogicException) of kunnen worden beïnvloed door dingen buiten de code, bijv. een bestand dat verwijderd is, verkeerde user input, etc. (RuntimeException).
Ik bedoel dus dat een compile error een soort van "spelfout" is. We zijn ergens een komma of een punt vergeten tijdens het typen. Terwijl een runtime error een fout is die tijdens de uitvoer van een request plaatsvindt. Correct?
Toevoeging op 11/03/2014 20:07:40:
Maar ook, als je een beetje goede compiler hebt, een niet bestaande method aanroepen of een niet bestaande variabele gebruiken.
Dat is wat ik bedoelde met "spelfout" :-)
>> of een niet bestaande variabele gebruiken
Is dat ook een compile error? Dus eigenlijk is wat je zelf verkeerd intypt een compile error?