In my Laravel 5.5 application, calls to DB::select which run a select query on a Postgresql database fail without showing any error in the Apache or Laravel error logs and trigger a "The connection was reset" message. This code sample runs as expected because the function get_users_with_roles
exists.
public function missing_function(Request $request) {
try{
$all = DB::select('SELECT * from get_users_with_roles()', []);
}catch(Illuminate\Database\QueryException $qe){
return json_encode($qe->getMessage());
}
return json_encode($all);
}
However, if I replace that SQL string with a function that doesn't exist:
public function missing_function(Request $request) {
try{
$all = DB::select('SELECT * from test()', []);
}catch(Illuminate\Database\QueryException $qe){
return json_encode($qe->getMessage());
}
return json_encode($all);
}
The connection is reset and I can't see any errors in the logs. If I run this erroneous query in a native Postgresql environment:
SELECT * from test();
I get a clear error message:
ERROR: function test() does not exist
LINE 1: select * from test()
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
It is particularly strange because this problem is not consistent. The try block sometimes catches the QueryException and displays the Postgresql error message as excepted.
I have tried adding
php_flag xcache.cacher Off
php_flag xcache.size 0
php_flag xcache.stat Off
to the .htaccess file but to no avail.
I need the ability to use the DB::select method because I rely heavily on Postgresql user-defined SQL and plpgsql functions in the application. I have a function which constructs the relevant SQL and passes it the DB::select method programmatically, so I need to be able to catch exceptions thrown when there is an error in the SQL, such as when the function is missing.
UPDATE
This problem seems to be with the way DB::select handles any SQL error. I've just tried this out with a function which exists but which throws an SQL error. Again, instead of allowing me to catch this in PHP with a try/catch block, it just resets the connection and doesn't log an error in either the Laravel log or the Apache log.
This question doesn't shed any light. The accepted answer there refers to the expected behaviour. In my environment, the QueryException isn't thrown or caught.
$all
contain when the exception is not thrown? – Biopsy\Throwable
(instead ofQueryException
) to see if maybe another exception is being thrown, and then later swallowed by another handler in your application? – Biopsy$all = DB::select('SELECT * from test()', []);
produces an$all
that contains an array of objects, even thoughtest
purportedly does not exist? – Biopsy$all = DB::select('SELECT * from get_users_with_roles()', []);
succeeds as expected. When I change the SQL to one that triggers an error in Postgresql, the Laravel try/catch block doesn't catch the exception. The function test() doesn't exist so it triggers an error. – Brighton