1

I have a Laravel/PHP application with the following code:

try {
        //gets the day of the last record for logged in user
        $lastRecord = $user->records()->orderBy('date', 'DESC')->first()->date;
        //convert to date
        $lastTime = \Carbon\Carbon::createFromFormat('Y-m-d', $lastRecord);
    }
    catch(Exception $e) {
        $lastTime = \Carbon\Carbon::now($user->timezone)->addDays(-1);
    }

but I still get the error:

ErrorException in Habit.php line 104:
Trying to get property of non-object

Now I'm confused.. The main idea was to fail sometimes, and then continue to the catch block. How come it's still raising an error?

sigmaxf
  • 7,998
  • 15
  • 65
  • 125
  • 3
    are you sure you aren't causing another exception in your catch block? you sure that `now()` unconditionally returns an object? what line is #104 in that? – Marc B May 12 '15 at 17:16
  • line 104 is: $lastRecord = $user->records()->orderBy('date', 'DESC')->first()->date; – sigmaxf May 12 '15 at 17:17
  • is it possible that Laravel has some debug setting that will raise every error even on a try/catch block? – sigmaxf May 12 '15 at 17:18
  • well, chase down the call tree. `var_dump($user); var_dump($user->records())` etc... and see which of those calls returns something OTHER than an object. – Marc B May 12 '15 at 17:19
  • 1
    can you post the call stack that you get with the exception? – Tim G May 12 '15 at 17:21
  • What's the namespace of the file you're in? (see also, below) – Alana Storm May 12 '15 at 17:26
  • it was the namespace, i should have used \Exception... still getting used to Laravel 5 – sigmaxf May 12 '15 at 17:35

2 Answers2

8

Just a guess, but try this instead

try {
    //gets the day of the last record for logged in user
    $lastRecord = $user->records()->orderBy('date', 'DESC')->first()->date;
    //convert to date
    $lastTime = \Carbon\Carbon::createFromFormat('Y-m-d', $lastRecord);
}
catch(\Exception $e) {
    $lastTime = \Carbon\Carbon::now($user->timezone)->addDays(-1);
}

That is, add a leading namespace separator in front of Exception. My guess is you're using this code in a namespaced file. When you do something like this

namespace App\Some\Somenamespace;
...
catch(Exception $e) {
...

PHP assumes you want to catch an exception with the name App\Some\Somenamespace\Exception. Since that's not the exception thrown, and there's no second catch for the global PHP \Exception, PHP complains about an uncaught exception. You'll want to explicitly refer to the exception as global

catch(\Exception $e) {

or import it into the current namespace

namespace App\Some\Somenamespace\;
use Exception;
...
catch(Exception $e) {
...

FWIW, I still do this all the time. Old habits are hard to break.

Alana Storm
  • 164,128
  • 91
  • 395
  • 599
  • that was it.. I was confused because the error was on another line.. but now it worked.. Thanks Alan! – sigmaxf May 12 '15 at 17:36
0

The exception says that you are accessing a property of a non-object. This means that either $user itself or one of the properies in chain does not exist. It may be possible to avoid this by checking return values.

But if you still want to catch the fatal error, you may install a global shutdown handler, like this:

register_shutdown_function( "shutdown_handler" );

function fatal_handler() {
    $errfile = "unknown file";
    $errstr  = "shutdown";
    $errno   = E_CORE_ERROR;
    $errline = 0;

    $error = error_get_last();

    if( $error !== NULL) {
        $errno   = $error["type"];
        $errfile = $error["file"];
        $errline = $error["line"];
        $errstr  = $error["message"];

        error_mail(format_error( $errno, $errstr, $errfile, $errline));
    }
}

taken from this SO post and this SO post.

Community
  • 1
  • 1
Shimon Rachlenko
  • 5,469
  • 40
  • 51
  • An `ErrorException` has the global PHP `\Exception` as an ancestor, and `catch (\Exception $e)` (or `catch (Exception $e)` in a non-namespaced file) will always catch an exception. – Alana Storm May 12 '15 at 17:24