一直想要定期写一些文章,每次都拖延症发作。
今天来分享一个在使用laravel 开发 api的时候遇见的一个很偶然间的异常。
[2020-11-13 17:34:03] local.ERROR: Argument 1 passed to Illuminate\\Routing\\Middleware\\ThrottleRequests::addHeaders() must be an instance of Symfony\\Component\\HttpFoundation\\Response, array given, called in /mnt/web/sp-api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php on line 133 {"exception":"[object] (TypeError(code: 0): Argument 1 passed to Illuminate\\Routing\\Middleware\\ThrottleRequests::addHeaders() must be an instance of Symfony\\Component\\HttpFoundation\\Response, array given, called in /mnt/web/sp-api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php on line 133 at /mnt/web/sp-api/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php:223)
看到有很多新手也遇见了这个问题,但是网上并没有什么明确的答案。
这是个很奇怪的错,ThrottleRequests是laravel用来进行限流的中间件,为什么会在这里出现异常?
断点调试之后发现 ,在项目中有一个 API请求签名验证中间件,当请求验证失败时会返回一个错误消息。
返回的内容是一个数组。
/**
* 请求时间戳超过有效期
*/
return ['state'=>false,'code'=>40001,'msg'=>'请求时间戳超过有效期'];
这个返回是一个不规范的返回,没有返回中间件应该返回的 Response 实例。
在一般情况下没有问题,但是当触发了限流之后。ThrottleRequests中间件拿到的注入对象不是Response实例就会出现抛出异常,找到了原因就好办了。
我们修改一下签名验证中间件,将要返回的数组放到响应body中,然后通过response()方法返回一个response实例
/**
* 请求时间戳超过有效期
*/
$response_data = return ['state'=>false,'code'=>40001,'msg'=>'请求时间戳超过有效期'];
return response($response_data);
问题解决,开发中要注意不要在中间件中直接返回数组,而是要返回一个响应实例,这样就不会遇见这种诡异的问题,都是不按规范开发导致的。