Laravel 自定义异常配置
Laravel Custom Exceptions Configuration
我一直在尝试在 Laravel 5.3 中实现一些自定义异常,但没有成功。
我创建了一个扩展异常 class 的 AppException。这样做的想法是,我想将一个用户附加到我的异常中,这样我就知道是谁触发了它并可以记录它。
所以我这样设置自定义异常:
class AppException extends Exception{
protected $userId;
public function __construct($message = '', $userId=0)
{
parent::__construct($message);
$this->userId = $userId;
}
}
现在我想要的是在我的控制器函数中使用 try catch,然后捕获异常,然后重新抛出应用程序异常,以便我可以附加用户。像这样:
try{
<< code here >>
}
catch(Exception $e){
throw new AppException($e->getMessage, $request->user()->id);
}
我发现我无法获得良好的跟踪堆栈,因为我从异常中记录的行是捕获中重新抛出的行,而不是实际异常中的行。
正确的设置方法是什么?我正在尝试以一种可以利用 Laravel 附带的内置 Handler.php 文件的方式来执行此操作,而不必在每个 try catch 中都输入日志代码。
谢谢!
尝试将实际异常附加到抛出的异常,例如:
class AppException extends \Exception
{
/**
* @var int
*/
private $userId;
/**
* @param \Exception $exception
* @param int $userId
*
* @return self
*/
public static function fromExceptionAndUserId(\Exception $exception, $userId)
{
$instance = new self(
$exception->getMessage(),
0,
$exception
);
$instance->userId = $userId;
return $instance;
}
/**
* @return null|int
*/
public function userId()
{
return $this->userId;
}
}
然后在你的控制器中:
try {
// ...
} catch (\Exception $exception) {
throw AppException::fromExceptionAndUserId(
$exception,
$request->user()->id
);
}
想法是不仅要使用实际的异常消息,还要将实际的异常附加为 $previous
异常。
使用命名构造函数的好处是您可以控制 AppException
异常消息的构造方式(同时还附加用户标识符),并且仍然能够使用原始 AppException
构造函数。它还让您可以自由地为不同的用例添加更多命名构造函数。
有关参考,请参阅
Exception
class 有一个 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;
}
}
或者只是简单地
class AppException extends Exception
{
public static function fromUserId($userId, Exception $previous = null)
{
return new static(sprintf('Exception thrown from `%s` userid', $userId), 0, $previous);
}
}
捕获 AppException
之后,您可以像这样迭代所有异常:
do {
printf("%s:%d %s (%d) [%s]\n", $e->getFile(), $e->getLine(), $e->getMessage(), $e->getCode(), get_class($e));
} while($e = $e->getPrevious());
示例:
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());
}
我一直在尝试在 Laravel 5.3 中实现一些自定义异常,但没有成功。
我创建了一个扩展异常 class 的 AppException。这样做的想法是,我想将一个用户附加到我的异常中,这样我就知道是谁触发了它并可以记录它。
所以我这样设置自定义异常:
class AppException extends Exception{
protected $userId;
public function __construct($message = '', $userId=0)
{
parent::__construct($message);
$this->userId = $userId;
}
}
现在我想要的是在我的控制器函数中使用 try catch,然后捕获异常,然后重新抛出应用程序异常,以便我可以附加用户。像这样:
try{
<< code here >>
}
catch(Exception $e){
throw new AppException($e->getMessage, $request->user()->id);
}
我发现我无法获得良好的跟踪堆栈,因为我从异常中记录的行是捕获中重新抛出的行,而不是实际异常中的行。
正确的设置方法是什么?我正在尝试以一种可以利用 Laravel 附带的内置 Handler.php 文件的方式来执行此操作,而不必在每个 try catch 中都输入日志代码。
谢谢!
尝试将实际异常附加到抛出的异常,例如:
class AppException extends \Exception
{
/**
* @var int
*/
private $userId;
/**
* @param \Exception $exception
* @param int $userId
*
* @return self
*/
public static function fromExceptionAndUserId(\Exception $exception, $userId)
{
$instance = new self(
$exception->getMessage(),
0,
$exception
);
$instance->userId = $userId;
return $instance;
}
/**
* @return null|int
*/
public function userId()
{
return $this->userId;
}
}
然后在你的控制器中:
try {
// ...
} catch (\Exception $exception) {
throw AppException::fromExceptionAndUserId(
$exception,
$request->user()->id
);
}
想法是不仅要使用实际的异常消息,还要将实际的异常附加为 $previous
异常。
使用命名构造函数的好处是您可以控制 AppException
异常消息的构造方式(同时还附加用户标识符),并且仍然能够使用原始 AppException
构造函数。它还让您可以自由地为不同的用例添加更多命名构造函数。
有关参考,请参阅
Exception
class 有一个 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;
}
}
或者只是简单地
class AppException extends Exception
{
public static function fromUserId($userId, Exception $previous = null)
{
return new static(sprintf('Exception thrown from `%s` userid', $userId), 0, $previous);
}
}
捕获 AppException
之后,您可以像这样迭代所有异常:
do {
printf("%s:%d %s (%d) [%s]\n", $e->getFile(), $e->getLine(), $e->getMessage(), $e->getCode(), get_class($e));
} while($e = $e->getPrevious());
示例:
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());
}