Using App::before to trap/catch PDOException Errors

Submitted by DragonI - 5 years ago

Here is how to beat Laravel to the punch when the database isn't playing nice. The error codes are specific to MySQL. You can easily substitute the error codes for whatever DB you are using. Below are 2 common errors. Here's a scrrenshot of the error page plus.google.com/113701899574492909448/posts/c4oAn7FDmLj

App::before(function($request, $response)
{
    /**
     * Laravel $code is always 500
     * message format:
     * SQLSTATE[HY000] [2002] No connection could be made because the target machine actively refused it.
     * SQLSTATE[HY000] [1049] Unknown database 'blah'
     */
    App::error(function(\PDOException $e, $code)
    {
        Log::error( 'FATAL DATABASE ERROR: ' . $code . ' = ' . $e->getMessage() );

        if ( App::Environment('local') )
        {
            $message = explode(' ', $e->getMessage());
            $dbCode = rtrim($message[1], ']');
            $dbCode = trim($dbCode, '[');

            // codes specific to MySQL
            switch ($dbCode) {
                case 1049:
                    $userMessage = 'Unknown database - probably config error:';
                    break;
                case 2002:
                    $userMessage = 'DATABASE IS DOWN:';
                    break;
                default:
                    $userMessage = 'Untrapped Error:';
                    break;
            }

            $userMessage = $userMessage . '<br>' . $e->getMessage();

        } else {
            // be apologetic but never specific ;)
            $userMessage = 'We are experiencing a bad bad problem. We are sorry for the inconvenience!';
        }

        return Response::view('frontend.error.databaseError', ['message' => $userMessage], $code);

    }); // end of App::error

});