You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中使用Twilio发送OTP时如何设置消息未送达异常处理

完善Laravel + Twilio OTP发送的异常处理

看起来你已经搞定了基础的OTP发送功能,接下来咱们把异常处理这块补全,覆盖从Twilio API错误到系统通用异常的各种场景,让你的代码更健壮:

1. 先引入必要的异常类

Twilio的PHP SDK自带专属异常,先把它引入进来,方便针对性捕获:

use Twilio\Exceptions\TwilioException;
use Twilio\Rest\Client;
use Illuminate\Support\Facades\Log;

2. 扩展try-catch逻辑,覆盖所有失败场景

我给你完善了send_otp方法的异常处理,包含日志记录、用户友好提示、不同错误场景的区分:

public function send_otp()
{
    // 先校验用户是否登录,避免空指针
    abort_unless(Auth::check(), 401, 'Please login first');
    
    try {
        $account_sid = env('TWILIO_ACCOUNT_SID');
        $auth_token = env('TWILIO_AUTH_TOKEN');
        $user = Auth::user();
        $number = $user->user_phone;
        
        // 简单校验手机号格式,提前拦截无效号码
        if (!preg_match('/^\+?[1-9]\d{1,14}$/', $number)) {
            return response()->json(['status' => 'error', 'message' => 'Invalid phone number format'], 400);
        }

        $client = new Client($account_sid, $auth_token);

        $message = $client->messages->create(
            $number,
            [
                'From' => '+12533368077',
                'Body' => "Your verification code is: {$user->user_otp}", // 给OTP加个友好前缀
            ]
        );

        // 发送成功后记录日志,方便后续排查
        Log::info("OTP sent successfully to {$number}", [
            'user_id' => $user->id,
            'twilio_message_sid' => $message->sid
        ]);
        
        return response()->json(['status' => 'success', 'message' => 'OTP sent to your phone']);

    } catch (TwilioException $e) {
        // 处理Twilio专属异常:无效号码、余额不足、认证失败等
        Log::error("Twilio API error when sending OTP", [
            'user_id' => $user->id ?? 'unknown',
            'phone_number' => $number,
            'error_code' => $e->getCode(),
            'error_message' => $e->getMessage()
        ]);

        // 根据Twilio官方错误码返回更精准的提示
        $userMessage = match ($e->getCode()) {
            21604 => 'The phone number you provided is invalid or cannot receive SMS.',
            21211 => 'The sender phone number is not a valid Twilio number.',
            21407 => 'Twilio account has insufficient balance to send messages.',
            default => 'Failed to send OTP. Please try again in a few minutes.'
        };

        return response()->json(['status' => 'error', 'message' => $userMessage], 500);

    } catch (\Exception $e) {
        // 处理系统通用异常:比如环境变量未配置、数据库错误等
        Log::error("Unexpected error when sending OTP", [
            'error_message' => $e->getMessage(),
            'trace' => $e->getTraceAsString()
        ]);
        
        return response()->json(['status' => 'error', 'message' => 'An unexpected error occurred.'], 500);
    }
}

3. 几个关键优化点

  • 提前校验:先检查用户登录状态和手机号格式,减少不必要的API调用
  • 日志分级:用info记录成功事件,error记录错误,方便后期排查问题
  • 用户友好:根据Twilio错误码返回不同提示,避免给用户展示技术术语
  • 响应规范:统一返回JSON格式,前端可以直接解析处理

4. 额外进阶建议

如果想更精准处理消息未送达的情况,可以在Twilio控制台设置状态回调Webhook,当消息状态变为failed或undelivered时,Twilio会主动通知你的后端,你可以做重试逻辑或者给用户发推送提醒。

内容的提问来源于stack exchange,提问作者Pranav Mandlik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:53:02