使用spatie/laravel-slack-slash-command自定义无参数错误响应
我来帮你解决这个问题!
首先得明确你之前的尝试无效的原因:你在handle方法里写的空参数判断永远不会执行。因为SignatureHandler在调用handle方法之前,会先执行内置的validate方法验证签名参数是否齐全,一旦发现day参数缺失,就会直接抛出InvalidInput异常,根本不会走到你自定义的handle逻辑里。
下面给你两种可行的解决方案,按需选择:
方法一:重写Handler的validate方法(推荐,最灵活)
直接在你的Projects Handler类中重写validate方法,完全接管参数验证逻辑,这样就能自定义参数缺失/格式错误时的响应,避免触发原有的异常。
修改后的完整代码:
<?php namespace App\SlashCommandHandlers; use Spatie\SlashCommand\Attachment; use Spatie\SlashCommand\AttachmentField; use Spatie\SlashCommand\Handlers\SignatureHandler; use Spatie\SlashCommand\Request; use Spatie\SlashCommand\Response; use App\Models\Retry42\Project; class Projects extends SignatureHandler { protected $signature = 'tasks day {day}'; // 重写validate方法,自定义参数验证逻辑 public function validate(): ?Response { // 检查参数是否缺失 if (!$this->input->hasArgument('day')) { return $this->respondToSlack("Argument Missing") ->withAttachment(Attachment::create() ->setColor('warning') ->setText("You must provide two digits between 00 and 13 after ex : /tasks day {00}") ); } // 提前验证参数格式 $day = $this->input->getArgument('day'); if(!preg_match("/^(0[0-9]|1[0-3])$/", $day)) { return $this->respondToSlack("Invalid argument, two digits between 00 and 13") ->withAttachment(Attachment::create() ->setColor('warning') ->setText("Project day must be two digits between 00 and 13") ); } // 验证通过,返回null,继续执行handle方法 return null; } public function handle(Request $request): Response { $slack_request = $this->getArgument('day'); // 这里无需再做参数验证,已经在validate里处理完成 $day = $slack_request; $project = 'Day '.$day; $project = Project::where('name', '=', $project)->firstOrFail(); $tasks = $project->tasks->toArray(); if (!count($tasks)) { return $this->respondToSlack("Sorry we could not get you any tasks for Day {$day}") ->withAttachment(Attachment::create() ->setColor('warning') ->setText("Try another day!") ); } $attachmentFields = collect($tasks)->reduce(function (array $attachmentFields, array $task) { $value = $task['description'] ?? ''; if($task['visible'] == 1) { $attachmentFields[] = AttachmentField::create('Name', $task['name'])->displaySideBySide(); $attachmentFields[] = AttachmentField::create('Description', $value)->displaySideBySide(); } return $attachmentFields; }, []); return $this->respondToSlack("Here are the tasks for Day {$day}") ->withAttachment(Attachment::create() ->setColor('good') ->setFields($attachmentFields) ); } }
方法二:全局捕获InvalidInput异常(适合统一处理所有SlashCommand错误)
如果你希望给所有SlashCommand的参数缺失错误统一设置响应格式,可以在Laravel的异常处理器中捕获该异常,自定义返回内容。
修改app/Exceptions/Handler.php:
use Spatie\SlashCommand\Exceptions\InvalidInput; use Spatie\SlashCommand\Attachment; // ... public function register() { $this->renderable(function (InvalidInput $e, $request) { // 判断是否为SlashCommand请求(路径需和你的路由配置一致) if ($request->is('slack')) { return $e->getResponse($request) ->setText("Argument Missing") ->withAttachment(Attachment::create() ->setColor('warning') ->setText("You must provide two digits between 00 and 13 after ex : /tasks day {00}") ); } }); }
这种方法适合全局统一错误格式,但如果不同Handler需要不同的错误提示,方法一更合适。
内容的提问来源于stack exchange,提问作者David Dacruz
相关产品推荐
相关产品推荐

