关于webman的异常和中间件问题

小阳光
class CrossDomain implements MiddlewareInterface
{
    public function process(Request $request, callable $next): Response
    {
        // 如果是options请求,不处理业务
        if ($request->method() == 'OPTIONS') {
            $response = response('');
        } else {
            $response = $next($request);  //如果控制器抛出异常,下面的给响应加跨域头不生效,不会走下面的代码。
        }
        $response->withHeaders([
            'Access-Control-Allow-Origin' => '*',
            'Access-Control-Allow-Methods' => 'GET,POST,PUT,DELETE,OPTIONS',
            'Access-Control-Allow-Headers' => 'Sig,ApiAuth,Content-Type,Authorization,X-Requested-With,Accept,Origin',
        ]);
        return $response;
    }
}

如果控制器 抛出异常,代码中下面的给响应加跨域头不会生效。
如果不抛出异常是正常的。但是有时候会在业务里面抛出业务异常,这是很常见的需求。

4622 2 0
2个回答

小阳光

目前我的做法是集成APP类重写onMessage里面的异常,但是这样做不优雅
或者去异常Handler里面添加头。也不优雅

截图

  • 暂无评论
walkor 打赏

更新 webman-framework 到 1.0.3 或者后续的更高保本。

  • 小阳光 2020-09-21

    我看了异常处理类, 如果处理异常类 里面再次抛出异常,那么这里的$response就是一个异常字符串,字符串调用response对象的方法会再次抛出异常。其实这个问题也可以忽略,不会造成什么严重后果。如果在异常的render 返回之前抛出异常,最后会直接输出异常字符串到浏览器。

    //跨域中间件
    public function process(Request $request, callable $next): Response
    {
    // 如果是options请求,不处理业务
    if ($request->method() == 'OPTIONS') {
    $response = response('');
    } else {
    $response = $next($request); //如果处理异常类 里面再次抛出异常,那么这里的$response就是一个异常字符串,字符串调用response对象的方法会再次抛出异常
    }
    $response->withHeaders([
    'Access-Control-Allow-Origin' => '*',
    'Access-Control-Allow-Methods' => 'GET,POST,PUT,DELETE,OPTIONS',
    'Access-Control-Allow-Headers' => 'Sign,ApiAuth,Content-Type,Authorization,X-Requested-With,Accept,Origin',
    ]);
    return $response;
    }

    //异常处理
    public function render(Request $request, Throwable $exception): Response
    {
    throw new \Exception('sendCode'); //注意这里
    //异常有自定义处理方法
    if (\method_exists($exception, 'render')) {
    return $exception->render();
    }
    // 参数验证错误
    if ($exception instanceof ValidationException) {
    return error($exception->getMessage());
    }
    // 处理自定义异常异常
    if ($exception instanceof BusinessException) {
    if ($exception->getCode()) {
    return reMsg($exception->getMessage(), $exception->getCode(), $exception->getData());
    } else {
    return error($exception->getMessage(), $exception->getData());
    }
    }
    //其他错误生产环境统一返回
    if (!config('app.debug')) {
    Log::error($exception->getMessage());
    return error('网络错误,请稍后再试', '');
    }
    return $this->sendDump($request, $exception);
    }

    /**
    这里是控制器里面的方法

    • @SWG\Post(path="/Tool/sendCode", tags={"Tool"},summary="发送验证码",
    • @SWG\Parameter(name="phone", type="string", required=true, in="formData",description="手机号码"),
    • @SWG\Parameter(name="type", type="string", required=false, in="formData",default="normal_ttl",description="类型"),
    • @SWG\Response(response=200,description="返回成功",@SWG\Schema(ref="#/definitions/BasicReturn"))
    • )
    • @throws \support\exception\BusinessException
      */
      public function sendCode(Request $request)
      {
      throw new \Exception('sendCode'); //注意这里
      $phone = $request->post('phone');
      $type = $request->post('type', 'normal_ttl');
      Validator::phone()->setName('手机号码')->check($phone);
      $this->push_msg->sendSmsCode($phone, $type);
      return success(L('Success'));
      }
  • walkor 2020-09-21

    根据接口规范,异常处理类render应该放回一个response对象,不应该再抛出异常。

  • 小阳光 2020-09-21

    好的

年代过于久远,无法发表回答
×
🔝