Laravel 自定义异常配置

ack*_*hez 0 php error-handling exception-handling exception laravel-5.3

我一直在尝试在 Laravel 5.3 中实现一些自定义异常,但没有成功。

我创建了一个扩展 Exception 类的 AppException 。这样做的想法是我想将用户附加到我的异常中,以便我知道是谁绊倒了它并可以记录它。

所以我像这样设置了我的自定义异常:

class AppException extends Exception{

    protected $userId;

    public function __construct($message = '', $userId=0)
    {
        parent::__construct($message);
        $this->userId = $userId;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我想要的是在我的控制器函数中使用 try catch ,然后捕获异常,然后重新抛出应用程序异常,以便我可以附加用户。像这样:

try{
    << code here >>
}
catch(Exception $e){
    throw new AppException($e->getMessage, $request->user()->id);
}
Run Code Online (Sandbox Code Playgroud)

我发现我无法获得良好的跟踪堆栈,因为我从异常记录的行是捕获中重新抛出的行,而不是来自实际异常的行。

设置它的正确方法是什么?我试图以一种可以利用 Laravel 附带的内置 Handler.php 文件的方式来做到这一点,而不必在每个 try catch 中放入日志代码。

谢谢!

Fed*_*kun 5

Exception班有一个previous说法,你可以用它来找回以前所有的异常。

class AppException extends Exception
{
    private $userId;

    public function __construct($userId, $message = '', $code = 0, Exception $previous = null)
    {
        $this->userId = $userId;

        parent::__construct($message, $code, $previous);
    }

    public static function fromUserId($userId, Exception $previous = null)
    {
        return new static($userId, sprintf('Exception thrown from `%s` userid', $userId), 0, $previous);
    }

    public function getUserId()
    {
        return $this->userId;
    }
}
Run Code Online (Sandbox Code Playgroud)

或者只是简单地

class AppException extends Exception
{
    public static function fromUserId($userId, Exception $previous = null)
    {
        return new static(sprintf('Exception thrown from `%s` userid', $userId), 0, $previous);
    }
}
Run Code Online (Sandbox Code Playgroud)

捕获后,AppException您可以像这样迭代所有异常:

do {
    printf("%s:%d %s (%d) [%s]\n", $e->getFile(), $e->getLine(), $e->getMessage(), $e->getCode(), get_class($e));
} while($e = $e->getPrevious());
Run Code Online (Sandbox Code Playgroud)

例子:

try {
    try{
        throw new RuntimeException('Something bad happened.');
    }
    catch(Exception $e){
        throw AppException::fromUserId(123, $e);
    }
} catch(AppException $e) {
    do {
        printf("%s:%d %s (%d) [%s]\n", $e->getFile(), $e->getLine(), $e->getMessage(), $e->getCode(), get_class($e));
    } while($e = $e->getPrevious());
}
Run Code Online (Sandbox Code Playgroud)