Fouten afhandelen met PHP

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • E-jey
  • Registratie: Juni 2001
  • Niet online
Ik heb al een aantal websites in PHP gemaakt en ik twijfel altijd wat een goede en nette manier is om fouten af te handelen. Toen ik begon met programmeren checkte ik altijd de return value van een functie, als die FALSE was dan handelde ik dat netjes af. Bij mijn eigen functies returnde ik altijd netjes FALSE als het fout ging.

Afgelopen maanden heb ik gewerkt met MVC frameworks als Kohana en Zend, inmiddels heb ik zelf een eenvoudig MVC framework gemaakt wat voldoet aan mijn eisen. Het is niet onnodig uitgebreid en ik begrijp het door en door. Ik probeer nu gebruik te maken van Exceptions, ik twijfel of ik dit wel op de goede manier gebruik, hoe gaan jullie hier mee om?

Hoe ik nu fouten afhandel:

- Gebruikers moeten alleen nette foutmeldingen zien, in productie staat display_errors dus op uit. Als er dus bijv. een E_PARSE error plaatsvind dan krijgt de gebruiker een leeg scherm te zien. Dit moet eigenlijk een http "interal server error" worden, ik moet alleen nog even uitvogelen of dit kan.

- Alle errors worden opgeslagen in een log bestand, dat is handig want dan kun je de website monitoren als het in productie zit en zo misschien nog een bug zoeken. Ik denk dat het ook handig om alle error meldingen een uniek nummer mee te geven. Als een gebruik met dat nummer contact opneemt dan kan ik daarmee in het log meer informatie zoeken.

- Via set_exception_handler() handel ik alle Exceptions af, via mijn eigen exception handler toon ik dus een nette error op het scherm voor alle nog niet gevangen exceptions.

- Via set_error_handler() heb ik me eigen error handler gedefinieerd, het enige wat die doet is een errorException gooien. Standaard worden alle errors dus omgezet in een Exception.

- PHP ondersteund wel Exceptions, maar een heleboel standaard functies niet. Die returnen nog FALSE als het fout gaat ipv een Exception gooien. Ik heb het idee dat dit een gebrek is van PHP en dat ze Exceptions nog niet helemaal volledig hebben geïmplementeerd. Daarom leek ik het me handig om alle errors om te zetten naar een Exception. Dan hoef je dus niet dit soort dingen te doen:

PHP:
1
2
3
4
5
6
7
8
9
10
11
    protected function query( $sql )
    {       
        $record_set =  @mysql_query( $sql );
        
        if ( ! $record_set )
        {
            throw new Exception( mysql_error() );
        }
        
        return $record_set;
    }


Over dit laatste puntje twijfel ik. Alle errors omzetten in een ErrorException leek me een goed idee, maar daar kom ik een beetje van terug. Ook E_NOTICE worden dan als Exception afgehandeld. Daarnaast krijg ik vaak de error: "Fatal error: Exception thrown without a stack frame in Unknown on line 0". Hier heb je dus helemaal niets aan. Het lijkt erop dat dit gebeurd als er tijdens het afhandelen van een Exception een nieuwe exception word gegooid.

De vraag is heel simpel: hoe handelen jullie fouten af in PHP en hebben jullie nog tips.

Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 15:32

Sebazzz

3dp

Gebruikers moeten alleen nette foutmeldingen zien, in productie staat display_errors dus op uit. Als er dus bijv. een E_PARSE error plaatsvind dan krijgt de gebruiker een leeg scherm te zien. Dit moet eigenlijk een http "interal server error" worden, ik moet alleen nog even uitvogelen of dit kan.
Als ik me niet vergis stuurt PHP wel een HTTP status van 500 mee bij een parsefout. Maar parsefouten kan je zelfs met unittesting al voorkomen, deze zouden niet eens een alpha of beta versie in mogen komen. Daarnaast denk ik dat een 'internal server error' ook niet bepaalde gebruiksvriendelijk is ;)
Alle errors worden opgeslagen in een log bestand, dat is handig want dan kun je de website monitoren als het in productie zit en zo misschien nog een bug zoeken. Ik denk dat het ook handig om alle error meldingen een uniek nummer mee te geven.
Ik zou aan de gebruiker slechts een korte foutbeschrijving en een eventueel foutnummer laten zien. Dan kan jij zelf een gedetailleerd log opvragen. Of nog simpeler, afhankelijk van de doelgroep: Gewoon 'er zijn x kritieke fouten gebeurt, x waarschuwingen. Neem contact op met x'.

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

  • WouZz
  • Registratie: Mei 2000
  • Niet online

WouZz

Elvis is alive!

Ik denk dat je op de goede weg bent. Het leuke van excepties is dat je ze af kan vangen (try/catch). Dit kan op verschillende lagen in je code. Wat nog leuker is aan excepties is dat je je eigen excepties kan definieren door over te erven van Exception. En Exception is gewoon een class, dus je kan zelf ook extra attributen specificeren in een sub-classe daarvan.

In jouw voorbeeld zou je bijvoorbeeld een MySQLQueryError kunnen gooien (of een platform onafhankelijke DatabaseQueryError). Door specifiek deze exceptie af te vangen zou je bijvoorbeeld een gebruiksvriendelijke foutmelding kunnen geven. Verder zou je ook een query attribuut in deze class kunnen opnemen. Hier zou je de query in kunnen bewaren waarmee te fout optrad, die je later eventueel in je foutmelding weer weer zou kunnen geven.

Verder is het jammer dat een hoop PHP functies alleen een false of -1 terug geven. Dit stamt nog uit het PHP3/4 tijdperk. Dit in tegenstelling tot Python, waar elke foutmelding een exceptie is en dus kan worden afgevangen.

On track


Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
Imho zou je weinig tegen php-fouten aan moeten lopen. Als je daar al tegenaan loopt, dan is een echt harde error wmb ook geen ramp.

Wmb is gewoon defensief programmeren en je eigen fouten afvangen voldoende.

Ik zal zeker niet zeggen dat ik foutloos programmeer, maar 1 regelige php-functies aanroepen veroorzaakt bij mij zo goed als nooit fouten, mijn fouten zitten eerder in mijn classes / functies en logica.
Oftewel niet blind een bestand openen en dan hopen dat php wel een nette foutmelding geeft als het niet bestaat, maar eerst checken of het bestand bestaat en zoja dan pas openen