Symfony 4,如何 return 正确地从服务 Class 错误 500 服务器
Symfony 4, how return properly a error 500 server from a service Class
从服务 class,如何管理异常和 return 错误 500?
例如,我有一个服务 class 'A' 从另一个服务 Class 'B' 调用。服务内容 'A' 是:
namespace App\Service;
use ...
class A
{
...
public static function foo(){
$tmp = [];
// do some stuff
if(isOK($tmp)){
return $tmp;
}else{
// return 500 with message
}
}
private static function isOK($tmp){
// do some stuff
}
}
我试过了:
namespace App\Service;
use ...
class A
{
...
public static function foo(){
$tmp = [];
// do some stuff
if(isOK($tmp)){
return $tmp;
}else{
// return 500 with message
}
}
private static function isOK($tmp){
try{
if(...) throw new \Exception();
}catch (HttpException $e){
dump('not valid data $tmp var in ' . __FUNCTION__,500);
exit;
}
}
}
但是我觉得我用的方法不是很好。如果我故意为 $tmp var 设置了一个错误的值,该过程将停止(如我所愿),并且在我使用此服务构建 symfony http 网页的情况下,会显示一个空白页面和我的消息,但这页面获得状态 200(不是 500 'internal server error')。
return 服务异常的 good/properly 方法是什么?
在 'service called from a controller used only for REST web service' 上下文 and/or 中 'service called from another service' 上下文 and/or 中是否有全局(symfony?oop php?)方法正确管理错误异常=] ,更传统地说,在 'service called from a classical http controller' 上下文中 ? (奖金:"service called from a custom Command Class" 中的 and/or)
也许我完全误解了这个问题,但我会说:从您的服务中抛出异常。
但是:如果你能正确处理它,你只会捕获到一个异常。在你的情况下,它看起来好像你不能在你的服务中处理它,所以你让它冒泡到适当的 Symfony 组件(在控制台命令、控制器或 Rest 端点之间不同)。
服务不应设置 500 代码,因为它不知道在哪个上下文中使用它。因此,您可能想抛出一个明确的 ServiceException 并在您的控制器中捕获它并将其转换为更有用的东西:
class A
{
public function foo(){
$tmp = [];
if($this->isOK($tmp)){
return $tmp;
}
throw new ServiceException('Failed checking $tmp');
}
private function isOK($tmp){
return false;
}
}
class TestController
{
/**
* @var A
*/
protected $a;
public function fooAction() {
try {
$this->a->foo();
} catch (ServiceException $e) {
throw new HttpException(500, $e->getMessage())
}
}
}
对于网络和休息,您必须确保您的异常具有正确的代码,然后将用于设置 HTTP 代码。
只有使用服务的代码才知道如何正确处理异常。由于状态代码在您的控制台命令中无关紧要,因此您无法捕捉到它。
但总的来说,您可以说这不是最佳实践,因为在将异常传递到下一个代码级别之前,您可能必须进行一些清理(关闭连接、关闭文件句柄、写入错误日志)。
控制台示例:
class MyCommand extends Command
{
protected function execute(InputInterface $input, OutputInterface $output)
{
$io = new SymfonyStyle($input, $output);
$a = new A();
try {
$this->a->foo();
} catch (ServiceException $e) {
// write to log file
$io->error('Service failed: ' . $e->getMessage());
return;
}
// do more stuff
}
}
从服务 class,如何管理异常和 return 错误 500? 例如,我有一个服务 class 'A' 从另一个服务 Class 'B' 调用。服务内容 'A' 是:
namespace App\Service;
use ...
class A
{
...
public static function foo(){
$tmp = [];
// do some stuff
if(isOK($tmp)){
return $tmp;
}else{
// return 500 with message
}
}
private static function isOK($tmp){
// do some stuff
}
}
我试过了:
namespace App\Service;
use ...
class A
{
...
public static function foo(){
$tmp = [];
// do some stuff
if(isOK($tmp)){
return $tmp;
}else{
// return 500 with message
}
}
private static function isOK($tmp){
try{
if(...) throw new \Exception();
}catch (HttpException $e){
dump('not valid data $tmp var in ' . __FUNCTION__,500);
exit;
}
}
}
但是我觉得我用的方法不是很好。如果我故意为 $tmp var 设置了一个错误的值,该过程将停止(如我所愿),并且在我使用此服务构建 symfony http 网页的情况下,会显示一个空白页面和我的消息,但这页面获得状态 200(不是 500 'internal server error')。
return 服务异常的 good/properly 方法是什么?
在 'service called from a controller used only for REST web service' 上下文 and/or 中 'service called from another service' 上下文 and/or 中是否有全局(symfony?oop php?)方法正确管理错误异常=] ,更传统地说,在 'service called from a classical http controller' 上下文中 ? (奖金:"service called from a custom Command Class" 中的 and/or)
也许我完全误解了这个问题,但我会说:从您的服务中抛出异常。
但是:如果你能正确处理它,你只会捕获到一个异常。在你的情况下,它看起来好像你不能在你的服务中处理它,所以你让它冒泡到适当的 Symfony 组件(在控制台命令、控制器或 Rest 端点之间不同)。
服务不应设置 500 代码,因为它不知道在哪个上下文中使用它。因此,您可能想抛出一个明确的 ServiceException 并在您的控制器中捕获它并将其转换为更有用的东西:
class A
{
public function foo(){
$tmp = [];
if($this->isOK($tmp)){
return $tmp;
}
throw new ServiceException('Failed checking $tmp');
}
private function isOK($tmp){
return false;
}
}
class TestController
{
/**
* @var A
*/
protected $a;
public function fooAction() {
try {
$this->a->foo();
} catch (ServiceException $e) {
throw new HttpException(500, $e->getMessage())
}
}
}
对于网络和休息,您必须确保您的异常具有正确的代码,然后将用于设置 HTTP 代码。
只有使用服务的代码才知道如何正确处理异常。由于状态代码在您的控制台命令中无关紧要,因此您无法捕捉到它。 但总的来说,您可以说这不是最佳实践,因为在将异常传递到下一个代码级别之前,您可能必须进行一些清理(关闭连接、关闭文件句柄、写入错误日志)。
控制台示例:
class MyCommand extends Command
{
protected function execute(InputInterface $input, OutputInterface $output)
{
$io = new SymfonyStyle($input, $output);
$a = new A();
try {
$this->a->foo();
} catch (ServiceException $e) {
// write to log file
$io->error('Service failed: ' . $e->getMessage());
return;
}
// do more stuff
}
}