• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Richtige Fehlerbehandlung (Exceptions)

bodo92

Aktives Mitglied
Hallo,

bisher habe ich bei einem "404 Error" eine Weiterleitung via header(Location: /fehler/404) gemacht, da das keine Saubere Lösung ist möchte ich jetzt eine Fehlerseite mit dem korrekten HTTP-Statuscode an den Client liefern, da bietet es sich ja an mit Exceptions zu arbeiten!

Alles funktioniert soweit wie gewünscht, da ich hierbei aber keinerlei Erfahrung habe würde ich gerne eure Meinungen und ggf. andere Vorschläge wie ich die Fehlerbehandlung einfacher/besser gestalten könnte..


Habe meine Klasse Fehler erstellt die von Exceptions erbt:
PHP:
<?php

class Fehler extends Exception {
    public function __construct($message, $code = 0, Exception $previous = null) {
        parent::__construct($message, $code, $previous);
    }
}

Hier ein Beispiel wo Fehler geschmissen werden:
PHP:
public function checkRoute() {
    if (array_key_exists($this->directory, $this->route)) {
        if (!array_key_exists($this->action, $this->route[$this->directory]['sites'])) {
            throw new Fehler('Seite nicht gefunden!', 404);
        }
    } else {
        throw new Fehler('Seite nicht gefunden!', 404);
    }
}

Und natürlich der try-catch Block:
PHP:
try {
    /**
     * Initialisierung der Anwendung!
     * 
     * Aufruf des Controllers
     */
} catch (Fehler $e) {
    switch ($e->getCode()) {
        case 403:
            header("HTTP/1.0 403 Forbidden");
            echo $e->getCode() . ' ' . $e->getMessage() . '<br>';
            echo $e->getFile() . ' ' . $e->getLine();
            break;
        case 404:
            header("HTTP/1.0 404 Not Found");
            echo $e->getCode() . ' ' . $e->getMessage() . '<br>';
            echo $e->getFile() . ' ' . $e->getLine();
            break;
        default:
            header("HTTP/1.0 500 Internal Server Error");
            echo $e->getCode() . ' ' . $e->getMessage() . '<br>';
            echo $e->getFile() . ' ' . $e->getLine();
            break;
    }
}

Die echo Ausgaben sind natürlich nur vorübergehend, hier sollte dann die Fehlerseite generiert werden!


Vielen Dank vorab.
LG Bodo
 
Um 403 und 500 brauchst du dich eigentlich garnicht zu kümmern. Btw. komm mal wieder ins Teamspeak. ;)
 
Ich würde anstelle von Fehler sowas wie FileNotFoundException nehmen. Also als Klassennamen, man kann jede Menge eigene Exception erstellen. Also wie ErrorException, BadRequestException etc....

Und nach außen hin zu den Besuchern würde ich lieber nur eine 404 Seite ausgeben zum Beispiel und da kannst du den HTTP Statuscode ja auch ändern.

DIe Exception ausgeben wär in meinen Augen nur ratsam wenn du das System in einen Dev Status packst, oder du machst das anhand eines Cookies den du auf deinem Rechner hast damit nur du die ausgaben siehst.

Oder wenn das System im Live Modus ist, würde sich vielleicht auch ein Logger anbieten, der loggt so zusagen alle geworfenen Exception und schickt dir diese per Mail oder sonst wie zu.

In meinen Augen, bzw. ist nun auch meine Meinung, finde es immer kritisch bzw. auch schlecht gemacht wenn man dem Besucher Code an den Kopf knallt und wenn es sogar nur ein Dateipfad ist wo der Fehler aufgetreten ist.

Zusatz: Ich finde eine Exception ist nicht dafür gedacht um den Besuchern einen Fehler mitzuteilen.

Zusatz vom Zusatz: html.de hat einen TS Server????
 
Ich würde anstelle von Fehler sowas wie FileNotFoundException nehmen. Also als Klassennamen, man kann jede Menge eigene Exception erstellen. Also wie ErrorException, BadRequestException etc....

Und nach außen hin zu den Besuchern würde ich lieber nur eine 404 Seite ausgeben zum Beispiel und da kannst du den HTTP Statuscode ja auch ändern.

DIe Exception ausgeben wär in meinen Augen nur ratsam wenn du das System in einen Dev Status packst, oder du machst das anhand eines Cookies den du auf deinem Rechner hast damit nur du die ausgaben siehst.

Oder wenn das System im Live Modus ist, würde sich vielleicht auch ein Logger anbieten, der loggt so zusagen alle geworfenen Exception und schickt dir diese per Mail oder sonst wie zu.

In meinen Augen, bzw. ist nun auch meine Meinung, finde es immer kritisch bzw. auch schlecht gemacht wenn man dem Besucher Code an den Kopf knallt und wenn es sogar nur ein Dateipfad ist wo der Fehler aufgetreten ist.

Zusatz: Ich finde eine Exception ist nicht dafür gedacht um den Besuchern einen Fehler mitzuteilen.

Zusatz vom Zusatz: html.de hat einen TS Server????
Ne, ich habe aber einen und da gammeln wir manchmal mit anderen Webdevlern noch drauf. Ganz lustig. PN mich wenn du die Daten haben willst.

Und wie du schon sagst, von der eigentlichen Exception sollte der Benutzer nichts mitkriegen. Wir benutzen hier auch einen Exception Transporter der die eigentliche Exception per Mail an uns weiterleitet.
 
Vielen Dank für eure Antworten :)

@nookie:
Weshalb würdest du keine 403, 500 Errors ausgeben? Finde es schon Hilfreich wenn man als Besucher/Nutzer Informationen dazu erhält.
Die Sache mit dem Mailen finde ich interessant, das würde sich in meinem Fall dann bei Error 500 oder default machen.
Ab Freitag könnte ich mich wieder in TS einfinden hab momentan Spätschicht.

@B3nnoX:
Ich glaube du hast mich hier missverstanden, die Echos sind nur zum Test hier wird dann die View der Fehlerseite generiert und ausgegeben.
Die Idee mit den Verschiedenen Exception-Klassen Finde ich gut, jedoch frage ich mich wie ich dann mehrere verschiedene Exceptions abfangen kann? Würde nur ungern mehrere try-catch Blöcke verschachteln..
Ich könnte doch auch direkt im Konstruktor der Exception-Klasse die Fehlerbehandlung (Ausgabe der Fehlerseite und das abbrechen der weiteren Ausführung) schreiben oder ist das nicht ratsam?
 
Vielen Dank für eure Antworten :)

@nookie:
Weshalb würdest du keine 403, 500 Errors ausgeben? Finde es schon Hilfreich wenn man als Besucher/Nutzer Informationen dazu erhält.
Die Sache mit dem Mailen finde ich interessant, das würde sich in meinem Fall dann bei Error 500 oder default machen.
Ab Freitag könnte ich mich wieder in TS einfinden hab momentan Spätschicht.

@B3nnoX:
Ich glaube du hast mich hier missverstanden, die Echos sind nur zum Test hier wird dann die View der Fehlerseite generiert und ausgegeben.
Die Idee mit den Verschiedenen Exception-Klassen Finde ich gut, jedoch frage ich mich wie ich dann mehrere verschiedene Exceptions abfangen kann? Würde nur ungern mehrere try-catch Blöcke verschachteln..
Ich könnte doch auch direkt im Konstruktor der Exception-Klasse die Fehlerbehandlung (Ausgabe der Fehlerseite und das abbrechen der weiteren Ausführung) schreiben oder ist das nicht ratsam?

Du musst die Blöcke auch nicht verschachteln.
PHP:
class FileNotFoundException extends Exception {}
class MaxLimitException extends Exception {}

try {
...
} catch(FileNotFoundException $e) {
...
} catch(MaxLimitException $e) {
...
}
 
Ich könnte doch auch direkt im Konstruktor der Exception-Klasse die Fehlerbehandlung (Ausgabe der Fehlerseite und das abbrechen der weiteren Ausführung) schreiben oder ist das nicht ratsam?

Das kannst du machen wie du lustig bist würde ich behaupten. Jedenfalls wüsste ich nicht was dagegen sprechen würde.


Wegen den mehreren Exception wäre das nun der Ansatz
PHP:
try {
    if ( !fileExists() ) { throw new BadFileException(); }
    if ( !isValidFile() ) { throw new InvalidFileException(); }
    if ( !hasValidSize() ) { throw new InvalidFileSizeException(); }
    // ...
} catch ( BadFileException $e ) {
    // ...
} catch ( InvalidFileException $e ) {
    // ...
} catch ( InvalidFileSizeException $e ) {
    // ...
}

EDIT: Verdammt zu langsam :D lässt du mir bitte auch mal Zeit rechtzeitig zu antworten :p
 
Ok, habs jetzt der Übersichthalber die Fehlerbehandlung direkt in der Exception geschrieben, ist aber noch nicht entgültig.

Beispiel:
PHP:
<?php

class PageNotFoundException extends Exception {
    public function __construct($message = '', $code = 0, Exception $previous = null) {
        parent::__construct($message, $code, $previous);

        $this->getErrorContent();
    }

    public function getErrorContent() {
        header("HTTP/1.0 404 Not Found");
        echo __CLASS__ . '<br>';
        echo $this->getFile() . ' ' . $this->getLine();
        exit();
    }
}
 
Du könntest zum Beispiel auch sowas hier machen, in der Klasse machst du noch eine Methode die dir zum Beispiel eine Mail schickt mit den ganzen Infos etc. Klar man könnte nun auch eine Logger klassen schreiben wo du das Exception Objekt übergibst. Viele Wege führen nach Rom. Aber wodrauf ich hinaus will ist folgendes

PHP:
try {

}catch(PageNotFoundExcetion $e) {
   // Wenn nun Mail Methode exisiert
   $e->sendErrorMail();
   $e->getErrorContent();
}

So hättest du zum Beispiel noch die Kontrolle was du wirklich machen willst mit der Exception.
 
Zurück
Oben