Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bubbling up exceptions in PHP?

Tags:

exception

php

I'm making a simple card game in PHP. When a user tries to play a card, I want to throw an exception if they can/can't. Rather than returning a number with a specific meaning (e.g. 1 means bad card, 2 means not your turn...etc.), I wanted to use customized exceptions. I'd catch these exceptions and display the message to the user.

I realize that exceptions are meant for out of the ordinary errors, but I think this is a good way to design my program.

The problem: my exceptions are being uncaught. I have a page called play.php which controls a class called Game, which has a Round that throws the exception. The play.php page gets the round from game, and makes function calls on it. However, it says the exception is not caught in round.

Is there a quick fix for this? How can I bubble up the exception from my Round class to my play.php page?

// in PLAY.php
try {
    $game->round->startRound($game->players);
} catch (RoundAlreadyStartedException $e) {
    echo $e->getMessage();
}

// in ROUND class
        if (!($this->plays % (self::PLAYS_PER_ROUND + $this->dealer))) {
            try {
                throw new RoundAlreadyStartedException();
            } catch (RoundAlreadyStartedException $e) {
                throw $e;
            }
            return;
        }

I've tried catching, not catching, throwing, rethrowing, etc.

like image 563
Lindz Avatar asked Nov 21 '10 19:11

Lindz


3 Answers

I agree with some of the comments that this is an odd way to achieve what you want to do, however I can't see any actual code problems. My test case:

class TestException extends Exception {
}

function raiseTestException() {
    try {
        throw new TestException("Test Exception raised");
    } catch(TestException $e) {
        throw $e;
    }
    return;
}

try {
    raiseTestException();
} catch(TestException $e) {
    echo "Error: " . $e->getMessage();
}

// result: "Error: Test Exception raised";

Is it actually the RoundAlreadyStartedException that isn't being caught, or some other error?

EDIT: wrapped in classes, on the off chance that it makes a difference (it doesn't):

class TestException extends Exception {
}

class TestClass {

    function raiseTestException() {
        try {
            throw new TestException("Test Exception raised");
        } catch(TestException $e) {
            throw $e;
        }
        return;
    }

}

class CallerClass {

    function callTestCallMethod() {
        $test = new TestClass();
        try {
            $test->raiseTestException();
        } catch(TestException $e) {
            echo "Error: " . $e->getMessage();
        }
    }

}

$caller = new CallerClass();
$caller->callTestCallMethod();

// result: "Error: Test Exception raised";
like image 194
Hamish Avatar answered Sep 20 '22 07:09

Hamish


I had this same strange behaviour with exceptions not bubbling. It turns out that I had the exceptions in another namespace but I wasn't explicitly using it and PHP didn't complain about that. So, adding using mynamespace\exceptions\MyException; solved it. Maybe that could be happening to you too.

HTH.

like image 24
Matias Gonzalez Avatar answered Sep 23 '22 07:09

Matias Gonzalez


I just this same problem in Laravel 4.2

As Laravel listens to the \Exception handler you can't use the root to throw an Exception and expect to bubble though the application unless you modify or extend Laravel. What you need is to create an empty Exception which extends \Exception for your namespace and then catch your namespaced Exception how ever you need to.

<?php
namespace Yournamespacehere;

class Exception extends \Exception {
}
like image 41
Lionel Morrison Avatar answered Sep 20 '22 07:09

Lionel Morrison