Hallo iedereen!

Ik ben nou al een hele tijd bezig met het developen van PHP applicaties.
Zo ben ik nu bijvoorbeeld bezig met een applicatie in Laravel, dat lukt me aardig, zo werk ik nu dus ook met een Laravel package die api data kan ophalen met een Http class. Nu is mij de vraag, het kan zijn dat de api het niet doet. Bijvoorbeeld: "U probeert verbinding te maken naar data die niet bestaat", "Er kan geen verbinding worden gemaakt naar de API" of "Even geduld AUB, te veel requests". Ik kan die bepaalde responses wel in een if/elseif/else statement stoppen of in een switch. Maar een paar mensen raden mij aan om try en catch te gebruiken. Ik kan er alleen geen kaas van maken. Kan iemand mij in Jip en Janneke taal uitleggen wanneer je precies try en catch gebruikt en hoe dat precies met de front end communiceert?

Alvast bedankt!
Zoals een bekende Nederlander eerder al constateerde:
Over smaak valt niet te twisten, maar over gebrèk aan smaak...

Dat brengt mij op een andere bekende Nederlander, met een onderbouwde mening over het schrijven van code.
Dit interview zou iedereen gezien moeten hebben.
https://www.vpro.nl/speel~WO_VPRO_035355~denken-als-discipline-noorderlicht~.html

Kwaliteit, correctheid en elegantie is waar code aan moet voldoen.

Daaruit voorvloeiend:

De competente programmeur is zich volledig bewust van de beperktheid van zijn eigen hersenpan.
Daarom benadert hij zijn programmeertaak met nederigheid.
Onder andere vermijdt hij slimmigheden als de pest.
Ad Fundum op 02/07/2021 13:07:25

Dit interview zou iedereen gezien moeten hebben.
https://www.vpro.nl/speel~WO_VPRO_035355~denken-als-discipline-noorderlicht~.html

Wat een pionier :-)


[size=xsmall]Toevoeging op 02/07/2021 16:41:59:[/size]

Geen idee of iemand hier vroeger wel eens naar een computerclub is geweest? Ik wel ... dat was er eentje speciaal voor met name Commodore computers. Daar ging ik dan spelletjes scoren. Hier 2 rete-oude filmpjes van zo'n club ... dit was zo snel het enige dat ik op YouTube kon vinden. Wel erg grappig. Het is uit 1991, dus schrik niet van de fancy kapsels en verbluffende kwaliteit :-)

[youtube]fgqfX0DZy7k[/youtube]

[youtube]iN-0G-EeTQk[/youtube]
Ozzie PHP op 02/07/2021 16:03:57

Wat een pionier :-)


Ja, en zijn standpunt "elegantie is een voorwaarde voor succes" is nog steeds actueel, de vraag hoe je programma's zo simpel en doeltreffend mogelijk maakt zou mijns inziens nog steeds voorop moeten staan. Dergelijke programma's zijn ook de meest efficiënte. Betere performance is zelfs beter voor het milieu, want kost minder stroom.

Wat Exceptions al kunnen throw-en zeg! :-)
Ad Fundum op 02/07/2021 20:41:23

Wat Exceptions al kunnen throw-en zeg! :-)

Ja, bij hoge uitzondering ... ;-)
Ozzie PHP op 02/07/2021 11:42:33

In het commentaar lees ik bij InvalidArgumentException: Invalid invoice number.

Dit roept bij mij al een vraag op. Een ongeldig argument kan zijn dat een gebruiker als factuurnummer 'abc' invult, terwijl er alleen cijfers (bijv. 123) zijn toegestaan. Het argument(type) is dus ongeldig. Echter, de omschrijving heeft het over een ongeldig nummer. Wat is een ongeldig nummer? Is 'abc' een ongeldig nummer omdat het niet uit cijfers bestaat, of is 598945343 een ongeldig nummer omdat er maar 100 facturen in het systeem zitten. Of leveren beide gevallen een ongeldig argument op?


Je stelt vragen die de code gewoon beantwoordt. :O

Kennelijk was het voorbeeld inderdaad te moeilijk...
>> Je stelt vragen die de code gewoon beantwoordt. :O

Klopt, in dit geval beperkte ik me even tot de naamgeving van de exception en het bijbehorende commentaar.

Natuurlijk, je dwingt als parameter een integer af ... maar wat is dan de bedoeling van InvalidArgumentException? Wanneer is het argument invalid? Is een niet bestaand (factuur)nummer een ongeldig argument? Lijkt me niet. Volgens mij is dat gewoon geldig, maar bestaat de factuur niet ... maar dat zou een NotFoundException opleveren. Snap je wat ik bedoel?
Hoe je het precies inkleed boeit me niet zo, maar:

Als je *geen* exceptions gebruikt moet je bij elke functie een "speciale waarde" teruggeven als "er iets aan de hand was" (ongeldige parameter, whatever). Dan krijg je dat gedoe wat je wel vaker in PHP hebt: 0 is een valide response, maar als het fout is gegaan is het false ... lekker handig. Vervolgens moet je dit controleren, en moet de aanroepende functie ook weer een foutcode retourneren, enz. Als je een beetje gelaagd aan het programmeren bent (functie die functie aanroept, die functie aanroept, enz), moet je dus al die lagen diep zo'n "if fout, then return false, else ga verder" gedoe inbouwen.

Voordeel van exceptions is dat je een exception gooit, en dat de code meteen terugspringt naar het punt waar je 'm wilt vangen. Dus meteen alle lagen omhoog schiet, zonder dat je er hocus-pocus code voor hoeft te schrijven die het alleen maar onleesbaarder maakt (tenminste, zo zie ik het).

Je code gaat er dus steeds vanuit dat alles in orde is, en is dus to the point en duidelijk leesbaar. Als er iets niet in orde is (kan zijn) moet je op een gegeven moment (ergens bovenin de aanroep) een try..catch inbouwen die de exception vangt en een nuttige foutmelding geeft / iets in het log plaatst.

Persoonlijk vind ik dit veel makkelijker programmeren (leesbaarder, minder gedoe). Met dat hele if speciale response loop je altijd het risico dat je het een keer vergeet, en wordt zo'n false opeens gezien als een geldige waarden (en heb je bijvoorbeeld opeens iets verkocht voor 0 euro; of -1 euro, als dat je "magische waarde" is).
Ok, dus dit is een manier om fouten of iets wat je zelf hebt ge-throw-ed, op een gecentraliseerde plek af te vangen.

Een voordeel dat ik zou verwachten, is dat overkoepelende code meer zicht heeft op de context voor de functies die het aanroept, en dat als er iets niet werkt, iets anders kan worden gedaan om verder te gaan met het uitvoeren van de code waar de Exception in voorkwam. Iets als een continue keyword in een catch -blok.
Maar die functionaliteit bestaat niet in PHP.

Ik ben nog steeds zoekende naar de meerwaarde van Exceptions, want PHP heeft ook nog ziets als trigger_error() en set_error_handler(). Dat doet dan precies hetzelfde. En het is ook niet ongebruikelijk om in speciale gevallen een statusvariabele 'by reference' mee te geven aan een functie als je daar iets afwijkends mee wilt.

Omdat er technisch geen verschil is, ben ik verder gaan kijken dan m'n neus lang is, en anderen merken op de je met Exceptions de afhandeling van fouten buiten de uit te voeren code verplaatst. Dat komt de leesbaarheid van code ten goede naarmate er meer foutsituaties worden afgehandeld. Ook wanneer er verschillende programmeurs werken aan de code, heb je eenzelfde manier van werken wat de leesbaarheid ook bevordert.
Dus mijn eerste gedachte, dat PHP het ook moest hebben omdat Java het ook heeft, klopt niet helemaal.

En omdat je Exceptions ook kunt gebruiken als doorgeefluik voor berichten, kan je het ook misbruiken voor gekke dingen als bijvoorbeeld routing, wat ik nou niet echt leesbaarder vind.

Al met al is het gebruik van Exceptions vooral een kwestie van smaak, en het kan de leesbaarheid van de code bevorderen door het aantal if-statements te verminderen bij bijvoorbeeld transacties, of door (fout)afhandeling buiten de code te plaatsen (wat Rob al zei).
Het een sluit het ander niet uit: errors zijn predefined exceptions.

Als je voldoende hebt aan errors alleen, kun je het bij errors laten. Heb je echter meer nodig, dan kun je errors ook als exceptions gebruiken. Zo kun je zelfs een systeem dat werkt met errors integreren in een ander systeem dat de voorkeur geeft aan exceptions.

Ozzie is bang dat er in ZIJN implementatie van mijn methode get(int $invoice_number) mét strict typing toch nog een string 'abc' door kan glippen. Kan gebeuren, maar dat zou je dan bijvoorbeeld zo kunnen afvangen:


<?php
try {
    $repo = new InvoiceRepository();
    $invoice = $repo->get($input);
} catch (TypeError $e) {
    // Ik moet iets aan mijn $input doen.
}
?>


De error als exception. Dit is waarschijnlijk niet de meest elegante separation of concerns, maar wel een zorg minder: de app hoeft niet meer vast te lopen op een string 'abc' die wordt afgehandeld als een int $invoice_number.

Gaan vliegen zonder voldoende brandstof is dom, maar je zou tijdens een vlucht wel eens zonder voldoende brandstof kunnen komen te zitten. Het eerste is een regelrechte fout (error), het tweede meer een zeldzame uitzondering (exception).

De Standard PHP Library (SPL) maakt een soortgelijk onderscheid tussen logic exceptions en runtime exceptions. De LogicException is een programmeerfout die je in productie niet meer tegen zou moeten komen: een harde error. De RuntimeException is een fout die je vooral in productie kunt verwachten: een zachtere uitzondering.

Met een LogicException ga je liever niet vliegen. Bij een RuntimeException ben je aan het vliegen en zorg je dat je zo lang mogelijk in de lucht blijft. In de praktijk zul je beide in productie tegenkomen, maar de LogicException is een bug die er nog uit moet en de RuntimeException een voldongen feit die je code elegant moet kunnen afhandelen.

Exceptions zijn inderdaad een kwestie van stijl, maar naarmate je ze langer en vaker gebruikt, smaken ze vaak naar meer. Uitzonderingen daargelaten. ;-)
>> Uitzonderingen daargelaten. ;-)

Ja, het zijn altijd weer de uitzonderingen ;-)

>> Ozzie is bang dat er in ZIJN implementatie van mijn methode get(int $invoice_number) mét strict typing toch nog een string 'abc' door kan glippen.

Dat was niet helemaal wat ik zei. Mijn vraag lag meer in de logica ... middels strict typing dwing je een integer af. Daarnaast heb je in jouw voorbeeld dan nog een 'ongeldig nummer'-uitzondering en een 'factuur niet gevonden'-uitzondering.

Mijn vraag is enerzijds wat heb je er in de praktijk aan om te loggen dat iemand een fout nummer heeft opgevraagd (of log je dit niet maar gaat het enkel om het tonen van een foutmelding aan de gebruiker?) en anderzijds wanneer treedt de 'factuur niet gevonden'-uitzondering op. Als het nummer niet klopt, wordt automatisch de factuur ook niet gevonden. Óf gooi je die exception uitsluitend op het moment dat het nummer wél klopt, maar het bestand niet aanwezig is?

Dit laatste kan natuurlijk, maar dan is dus de vraag: hoe kan een bestand ineens niet meer aanwezig zijn. Dat moet dan gebeurd zijn door een handmatige actie/vergissing van een programmeur. Maar moet je daar dan speciaal een exception voor inbouwen? Kortom ... hoe ver moet je gaan?

Reageren