Laravel Attribute set捕获异常保持属性原值的最佳方案
Laravel模型属性修改器捕获间隔解析异常的最优实现
直接在属性set闭包内做定向异常捕获即可,仅捕获明确预期的Carbon\Exceptions\InvalidIntervalException异常,不要做全局异常兜底,避免吞掉其他非预期错误提高排查成本。
实现逻辑很简单:当传入值解析成功时正常返回格式化后的spec值;解析抛出目标异常时,直接返回该属性对应的原始值,即可实现异常触发时属性值不被覆盖的效果。
以名为interval的间隔属性为例,完整代码如下:
<?php namespace App\Models; use Carbon\CarbonInterval; use Carbon\Exceptions\InvalidIntervalException; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Casts\Attribute; class YourModel extends Model { protected function interval(): Attribute { return Attribute::make( set: function ($value) { try { return CarbonInterval::fromString($value)->spec(); } catch (InvalidIntervalException $e) { // 解析失败时返回属性原始值,保持原有内容不变 // 第二个参数是新建模型无原始值时的默认值,可按需调整 return $this->getOriginal('interval', 'P1D'); } } ); } }
注意事项
- 禁止使用
catch (\Exception $e)这类全量异常捕获写法,仅捕获你明确预判会出现的InvalidIntervalException,避免把类不存在、语法错误等非预期问题吞掉。 getOriginal()方法的第二个参数是默认值,对应模型首次创建、还没有存过原始值时传入无效内容的兜底返回值,你可以根据业务实际需要调整,不需要默认值就传null即可。- 捕获异常后如果有排查需要可以加日志记录,不要加额外的业务逻辑,保持修改器逻辑单一,避免产生额外副作用。
内容的提问来源于stack exchange,提问作者OurBG
相关产品推荐
相关产品推荐

