自定义Exception异常

本文详细介绍如何创建自定义异常类并应用于代码中,通过继承Exception类实现多种构造方法,包括无参、带消息字符串及异常原因等。同时,演示了在set方法中如何使用自定义异常处理非法输入,确保程序的健壮性和可读性。

自定义异常构建

首先写一个自定义异常,继承Exception,代码如下

public class NoMappingParamString extends Exception {
    /*无参构造函数*/
    public NoMappingParamString(){
        super();
    }
    
    //用详细信息指定一个异常
    public NoMappingParamString(String message){
        super(message);
    }
    
    //用指定的详细信息和原因构造一个新的异常
    public NoMappingParamString(String message, Throwable cause){
        super(message,cause);
    }
    
    //用指定原因构造一个新的异常
    public NoMappingParamString(Throwable cause) {
        super(cause);
    }
}

使用自定义异常

如果自定义异常是为了提示,一定要用try..catch,不要直接用throw往外抛。这样只能被框架捕获。

    /*结果resultType字段set方法*/
    public void setResultType(String resultType) {
        this.resultType = resultType == null ? null : resultType.trim();  //resultType结果封装
        
        //自定义一个resultTypeString字段,用来根据resultType的值(1,2,3)自动生成对应的文本
        /*这样写的好处是集中管理,后台代码中只在此处管理,不好的地方是运营时突然加一个值就会返回未知类型,要更新要把后端重新编译发布,也就意味着要重启(把值传给前端让前端判断是不用重启的)。这种方案只适用于类型固定的字段*/
        if (resultType!=null) {
            int rt = Integer.parseInt(resultType);   //将flag转换为int值
            switch (rt) {  //判断属于那种类型,就给resultTypeString赋予对应的值
            case 1:
                resultTypeString ="未处理";
                break;
            case 2:
                resultTypeString ="自动解除";
                break;
            case 3:
                resultTypeString ="已解除";
                break;
            default:
                resultTypeString = "未知类型";
                /*这里一定要try catch异常,因为这是set方法,throw出去大部分情况是被框架获取*/
                try {   
                    /*实例化自定义异常*/
                    NoMappingParamString exception = new NoMappingParamString("resultType类型未完善"+"未知resultType:"+resultType);
                    /*抛出异常*/
                    throw exception;
                } catch (NoMappingParamString e) { //捕获异常
                    System.err.println("异常信息:"+e.getMessage());  //获取异常信息,就是上面传的message
                    e.printStackTrace();  //把栈信息打印出来
                }
                break;
            }
        }else {
            resultTypeString = "";  //如果flag为null返回为空
        }
    }

仅仅为了提示,又不想自定义一个Exception,可以用RuntimeException。这个可以抛出异常,并准确定位,缺点是不能处理这个异常自定义异常的话可以捕获并且处理

public Queue(int initialSize) {
        if (initialSize >= 0) {
            this.maxSize = initialSize;
            data = new Object[initialSize];
        }else {
            throw new RuntimeException("初始化大小不能小于0:"+initialSize);
        }
    }

 

转载于:https://www.cnblogs.com/aeolian/p/10449506.html

<think> 我们正在讨论Laravel中自定义异常处理,特别是关于Exception类中的context()方法。 根据用户提供的引用,我们知道Laravel使用全局异常处理器(\App\Exceptions\Handler)来捕获异常。在自定义异常时,我们可以重写context()方法来添加额外的上下文信息。 在Laravel中,当我们自定义异常类时,可以重写context()方法,该方法返回一个数组,包含我们想要添加到异常日志中的额外上下文数据。 例如,假设我们有一个自定义异常类CustomException,我们可以这样实现: ```php <?php namespace App\Exceptions; use Exception; class CustomException extends Exception { // ... /** * 获取异常的上下文信息 * * @return array */ public function context() { return ['user_id' => auth()->id(), 'data' => ['key' => 'value']]; } } ``` 当这个异常被抛出且未被捕获时,Laravel的异常处理器会记录这个异常。在记录时,除了异常的基本信息,还会将context()方法返回的数组内容一并记录到日志中。 引用[2]中提到,异常处理器会先上报异常记录到日志文件,然后渲染异常响应。如果我们重写了context()方法,那么这些额外的上下文信息就会出现在日志中。 另外,引用[3]提到异常Exception类的对象,在遇到无法修复的状况时抛出。我们可以通过自定义异常来丰富异常信息,这对于调试和错误追踪非常有用。 因此,用户想要了解的自定义Exception异常的context()方法的使用和实现,就是通过继承Exception类并重写context()方法,返回额外的上下文数据数组。 下面是一个更具体的示例,展示如何在自定义异常中使用context()方法: ```php <?php namespace App\Exceptions; use Exception; class OrderException extends Exception { protected $orderId; public function __construct($orderId, $message = "", $code = 0, Throwable $previous = null) { $this->orderId = $orderId; parent::__construct($message, $code, $previous); } public function context() { return [ 'order_id' => $this->orderId, 'user' => auth()->user() ? auth()->user()->id : null, ]; } } ``` 在这个例子中,我们创建了一个订单相关的异常,它接收一个订单ID,并在context()方法中返回包含订单ID和当前用户ID的数组。这样,当这个异常被记录时,日志中就会包含这些信息,便于我们追踪问题。 总结: 1. 自定义异常类继承自Exception2. 重写context()方法,返回一个数组,包含你希望在日志中看到的额外上下文信息。 3. 当异常被抛出且未被捕获时,这些上下文信息会被自动记录到日志中。 注意:context()方法只有在异常被Laravel的异常处理器记录时才会被调用。如果你手动捕获异常并记录,需要自己处理上下文信息。 另外,用户提到的引用[2]中还提到了将异常上报到Sentry系统,同样,通过context()方法添加的上下文信息也会被Sentry捕获,因为Laravel的异常处理器在记录日志时会使用这些上下文。 因此,使用context()方法可以方便地为异常日志添加有用的上下文信息,提高调试效率。 </think> 在 Laravel 中自定义 Exception 异常的 `context()` 方法主要用于向异常日志中添加结构化上下文数据,增强错误调试信息。以下是具体实现和使用方式: ### 一、context() 方法的作用 1. **补充日志信息**:当异常被记录到日志时(默认通过 `Log::error()`),`context()` 返回的数组会自动合并到日志条目中[^2]。 2. **结构化数据**:相比在异常消息中拼接字符串,`context()` 更适合传递键值对形式的结构化数据(如用户ID、请求参数等)[^3]。 3. **错误追踪**:第三方错误监控系统(如 Sentry)可直接获取这些上下文数据辅助调试[^2]。 ### 二、实现步骤 1. **创建自定义异常** ```php // app/Exceptions/CustomException.php namespace App\Exceptions; use Exception; class CustomException extends Exception { protected $userId; public function __construct($message, $userId) { parent::__construct($message); $this->userId = $userId; } // 重写context()方法 public function context() { return [ 'user_id' => $this->userId, // 自定义字段 'request_data' => request()->all() // 获取当前请求数据 ]; } } ``` 2. **抛出异常示例** ```php // 控制器中使用 throw new \App\Exceptions\CustomException( '订单创建失败', auth()->id() // 传递用户ID到异常 ); ``` ### 三、运行效果 当异常触发时,日志会自动记录上下文(日志文件 `storage/logs/laravel.log`): ``` [2023-01-01] local.ERROR: 订单创建失败 {"user_id":123,"request_data":{"product_id":456}} [stack trace] ``` ### 四、结合异常处理器 在 `app/Exceptions/Handler.php` 的 `report()` 方法中,上下文数据会被自动处理: ```php public function report(Exception $e) { // 自动捕获 context() 返回的数据 parent::report($e); // 推送到Sentry(示例) if ($this->shouldReport($e)) { app('sentry')->captureException($e); } } ``` ### 五、注意事项 1. **敏感数据过滤**:避免在 `context()` 返回密码等敏感信息 2. **性能影响**:涉及数据库查询的操作需谨慎,可能加重异常处理负担 3. **异常继承**:自定义异常应继承 `\Exception` 或其子类(如 `Illuminate\Http\Exceptions\HttpResponseException`) 通过 `context()` 方法,开发者可以精准传递调试所需的上下文信息,极大提升生产环境错误诊断效率[^1][^3]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值