44

All I'm trying to do is verify a query.

'SELECT * from table_that_does_not_exist'

Without that erroring out, I'd like to know it failed so I can return a response that states "Error: table does not exist" or the generic error.

AAEM
  • 1,837
  • 2
  • 18
  • 26
KingKongFrog
  • 13,946
  • 21
  • 75
  • 124
  • If you're using `Eloquent` for your queries, you could use `firstOrFail()` on a `DB::raw()` query. Or a `try{ } catch (Illuminate\Database\QueryException $ex){ }` – Tim Lewis Nov 12 '15 at 19:51
  • I tried the try catch however, it still shows the error. For example: try { $results = DB::connection('myDB')->select('BAD TEXT QUERY SHOULD FAIL'); } catch ( Illuminate\Database\QueryException $e) { // Don't do anything } – KingKongFrog Nov 12 '15 at 19:57
  • 2
    `try { $results = \DB::connection("example")->select(\DB::raw("SELECT * FROM unknown_table"))->first(); } catch(\Illuminate\Database\QueryException $ex){ die("Caught an error"); }` Throws and `dies` "Caught an error". Did you have the \ before Illuminate? I just realized I forgot that in my first comment. Also, you `$ex` would extend the base `Exception` class, so you can call `$ex->getMessage()` to return the exact error. – Tim Lewis Nov 12 '15 at 20:02
  • @TimLewis That was perfect thanks! Feel free to add that as answer so I can reward you with a million dollars. – KingKongFrog Nov 12 '15 at 20:53
  • Haha no problem, will do! – Tim Lewis Nov 12 '15 at 20:54

4 Answers4

90

The simplest way to catch any sql syntax or query errors is to catch an Illuminate\Database\QueryException after providing closure to your query:

try { 
  $results = \DB::connection("example")
    ->select(\DB::raw("SELECT * FROM unknown_table"))
    ->first(); 
    // Closures include ->first(), ->get(), ->pluck(), etc.
} catch(\Illuminate\Database\QueryException $ex){ 
  dd($ex->getMessage()); 
  // Note any method of class PDOException can be called on $ex.
}

If there are any errors, the program will die(var_dump(...)) whatever it needs to.

Note: For namespacing, you need to first \ if the class is not included as a use statement.

Also for reference:

Laravel 5.5 API - Query Exception

Laravel 8.x API - Query Exception

Tim Lewis
  • 27,813
  • 13
  • 73
  • 102
  • 4
    For Laravel 5.5 this answer doesn't work for me. Please refer to this question: https://stackoverflow.com/questions/49881563/when-calling-dbselect-why-do-i-get-a-the-connection-was-reset-message – DavidHyogo Apr 21 '18 at 03:13
  • In my case sometime mysql server goes down, we are working to fix though. IN the meantime, how to handle this connection error showing (SQLSTATE[HY000] [1045] Access denied for user) explicitly and show soft error message? – Anto S Aug 23 '20 at 06:36
  • @Butterfly That's beyond the scope of this question. Try searching Stackoverflow for that error, or ask a new question. – Tim Lewis Aug 24 '20 at 03:59
  • 1
    Reference link is broken, this one works: https://laravel.com/api/8.x/Illuminate/Database/QueryException.html – Asaf M Sep 22 '21 at 13:49
  • @AsafM Thanks for that! Looks like they retired the Laravel 5.1 API; your link, or https://laravel.com/api/5.5/Illuminate/Database/QueryException.html are both acceptable. Will update answer. Cheers! – Tim Lewis Sep 22 '21 at 13:51
  • 1
    Worked for Lumen 8, thanks! I was using just `Exception` which didn't catch `QueryException`, now when specified `\Illuminate\Database\QueryException` it captures it! – Siniša Feb 12 '22 at 06:48
23

Wrap the lines of code you wish to catch an exception on using try-catch statements

try
{
//write your codes here
}
catch(Exception $e)
{
   dd($e->getMessage());
}

Do not forget to include the Exception class at the top of your controller by saying

Use Exception;
Ogbonna Vitalis
  • 7,969
  • 2
  • 11
  • 21
11

If you want to catch all types of database exceptions you can catch it on laravel Exception Handler

if ($exception instanceof \PDOException) {
    # render a custom error
}

for more details about how to use laravel Exception Handler check https://laravel.com/docs/7.x/errors

Ashraf Hefny
  • 508
  • 1
  • 6
  • 20
  • 1
    Please really should upvote this. Best answer by far, thanks! – Ryan Charmley Oct 22 '19 at 22:55
  • [reference link](https://laravel.com/docs/7.x/errors) for detailed documentation, Thanks in Advance – VishalParkash May 20 '20 at 14:22
  • Thanks Ashraf , that is very helpful. Example in app/Exceptions/Handler.php : public function report(Throwable $exception) { if ($exception instanceof \PDOException) { dd("Error connecting to database, please turn on MySQL database server"); } parent::report($exception); } – Naim R. Jul 02 '21 at 07:07
6

Laravel 8.x

    try {
        $model->save(); // Use Eloquent: https://laravel.com/docs/8.x/eloquent
    } catch (\Throwable $e) {
        return 'My error message';
    }

Note* Need to specify \Throwable $e no Throwable $e.