从方法内部处理异常
Handle Exception From Within Method
我正在使用外部服务(即支付提供商的服务)的 API 为我的网站实施支付。
假设用户点击 'BUY',然后我们转到我的控制器,它说的是:
public function buyFunction() {
$result = $this->ExternalService->pay();
if ($result->success == true) {
return 'We are happy';
}
}
我还创建了前面提到的 externalService
,它具有 pay()
方法:
class ExternalService {
public function pay() {
response = //Do stuff with Guzzle to call the API to make the payment
return response;
}
}
现在,有时候事情会出错。
假设 API returns 一个错误 - 这意味着它抛出 GuzzleException - 我该如何处理?
理想情况下,如果有错误,我想记录它并将用户重定向到一个页面并告诉他出了点问题。
我试过的
我尝试在 pay() 函数中使用 try/catch 语句并使用 abort(500)
但这不允许我重定向到我想要的页面。
我试过在 pay() 函数中使用 try/catch 语句并使用 return redirect('/mypage')
但这只是 returns 到控制器的重定向对象,它然后在尝试调用 result->success
时失败
我试过使用数字 2,但也在控制器方法中添加了一个 try/catch 块,但没有任何改变。
最后,我找到了两个解决方案。在两者中,我都在 pay() 方法中使用了 try/catch 块。然后我 return 0;
并检查控制器 if (result == 0)
或者我在 pay() 方法的 try/catch 块内使用 abort( redirect('/mypage') );
。
处理这个问题的正确方法是什么?
如何使用try/catch块?
根据我的经验,避免处理异常让它们通过并使用 try catch 相应地处理它们。这是最实用的方法。或者,您最终会在奇怪的地方检查结果是否正确,例如。 if ($result) {...}
。假设一切顺利,除非抛出异常。额外奖励:除非你特别需要,否则永远不要用 Exception $e
捕捉 Pokemon!
class ExternalService {
public function pay() {
try {
response = $client->get(...);
} catch (BadResponseException $exception) {
Log::warning('This should not happen check payment api: ' . $exception->getMessage());
throw new PaymentException('Payment did not go through');
}
return response;
}
}
假设您有自己的异常。
class PaymentException extends HttpException
{
public function __construct(?\Exception $previous = null)
{
parent::__construct(Response::HTTP_BAD_REQUEST, 'Unexpected error processing the payment', $previous);
}
}
这使您能够在控制器中处理流,在控制器中处理重定向是有意义的。有时,如果异常对于 Web 应用来说是不可或缺的或常见的,它也可以由异常处理程序来处理。
class PaymentController {
public function pay(PaymentService $service) {
try {
$payment = $service->buyFunction();
} catch (PaymentException $exception) {
return redirect()->route('app.payment.error');
}
return view('app.payment.success', compact('payment'));
}
}
我正在使用外部服务(即支付提供商的服务)的 API 为我的网站实施支付。
假设用户点击 'BUY',然后我们转到我的控制器,它说的是:
public function buyFunction() {
$result = $this->ExternalService->pay();
if ($result->success == true) {
return 'We are happy';
}
}
我还创建了前面提到的 externalService
,它具有 pay()
方法:
class ExternalService {
public function pay() {
response = //Do stuff with Guzzle to call the API to make the payment
return response;
}
}
现在,有时候事情会出错。 假设 API returns 一个错误 - 这意味着它抛出 GuzzleException - 我该如何处理?
理想情况下,如果有错误,我想记录它并将用户重定向到一个页面并告诉他出了点问题。
我试过的
我尝试在 pay() 函数中使用 try/catch 语句并使用
abort(500)
但这不允许我重定向到我想要的页面。我试过在 pay() 函数中使用 try/catch 语句并使用
时失败return redirect('/mypage')
但这只是 returns 到控制器的重定向对象,它然后在尝试调用result->success
我试过使用数字 2,但也在控制器方法中添加了一个 try/catch 块,但没有任何改变。
最后,我找到了两个解决方案。在两者中,我都在 pay() 方法中使用了 try/catch 块。然后我 return 0;
并检查控制器 if (result == 0)
或者我在 pay() 方法的 try/catch 块内使用 abort( redirect('/mypage') );
。
处理这个问题的正确方法是什么? 如何使用try/catch块?
根据我的经验,避免处理异常让它们通过并使用 try catch 相应地处理它们。这是最实用的方法。或者,您最终会在奇怪的地方检查结果是否正确,例如。 if ($result) {...}
。假设一切顺利,除非抛出异常。额外奖励:除非你特别需要,否则永远不要用 Exception $e
捕捉 Pokemon!
class ExternalService {
public function pay() {
try {
response = $client->get(...);
} catch (BadResponseException $exception) {
Log::warning('This should not happen check payment api: ' . $exception->getMessage());
throw new PaymentException('Payment did not go through');
}
return response;
}
}
假设您有自己的异常。
class PaymentException extends HttpException
{
public function __construct(?\Exception $previous = null)
{
parent::__construct(Response::HTTP_BAD_REQUEST, 'Unexpected error processing the payment', $previous);
}
}
这使您能够在控制器中处理流,在控制器中处理重定向是有意义的。有时,如果异常对于 Web 应用来说是不可或缺的或常见的,它也可以由异常处理程序来处理。
class PaymentController {
public function pay(PaymentService $service) {
try {
$payment = $service->buyFunction();
} catch (PaymentException $exception) {
return redirect()->route('app.payment.error');
}
return view('app.payment.success', compact('payment'));
}
}