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

为什么Java自定义异常UniqueValueException未被重新抛出与捕获?

问题根因

你的checkCustomerUniqueValues方法内部已经将抛出的UniqueValueException捕获消化,没有向上重新抛出,因此上层addCustomer根本接收不到该异常,自然会继续执行后续的写入逻辑。

查看checkCustomerUniqueValues代码可以看到对应问题:

catch (UniqueValueException e) {
    e.printStackTrace();
    // 此处仅打印了异常栈,没有重新抛出,异常到此终止
}

执行完catch块后方法会正常返回,对于addCustomer来说checkCustomerUniqueValues调用是正常结束的,因此会继续向下执行写入文件的流程。


修复方案

1. 调整checkCustomerUniqueValues的异常处理逻辑

推荐直接移除该方法内的UniqueValueException捕获分支,让业务异常自然向上抛出:

public static void checkCustomerUniqueValues(Customer c) throws UniqueValueException{
    Scanner inFileStream = null;
    String custID = "";
    String name = "";
    float creditBalance = 0;
    String telephone = "";
    String address = "";
    try {
        inFileStream = new Scanner(new File("Digicel_Customers.txt"));
        while (inFileStream.hasNext()) {
            custID = inFileStream.next();
            name = inFileStream.next();
            creditBalance = inFileStream.nextFloat();
            telephone = inFileStream.next();
            address = inFileStream.nextLine();
            if (custID.equals(c.getCustID())) {
                throw new UniqueValueException("Customer ID already exists.");
            }
            else if(telephone.equals(c.getTelephone().toString())){
                throw new UniqueValueException("Telephone number already in use.");
            }
        }   
    } 
    // 移除UniqueValueException的捕获分支
    catch (FileNotFoundException e) {
        e.printStackTrace();
        throw new RuntimeException("读取客户文件失败", e);
    } catch (Exception e) {
        e.printStackTrace();
        throw new RuntimeException("校验客户唯一性出现未知错误", e);
    }
    finally{
        if(inFileStream != null) {
            try {
                inFileStream.close();
            }catch(Exception e) {
                System.err.println("\nAn unexpected error occured.");
            }   
        }
    }
}

如果你需要在该方法内打印异常栈,也可以保留捕获分支并补充重新抛出的逻辑:

catch (UniqueValueException e) {
    e.printStackTrace();
    throw e; // 补充该行重新抛出业务异常
}

2. 修复AdminGui的异常提示逻辑

当前AdminGui的异常捕获分支中弹出的是默认值为空的returnString,用户看不到具体错误,修改为读取异常的提示信息:

catch(UniqueValueException e1){
    JOptionPane.showMessageDialog(parentFrame,e1.getMessage(),"Form Error",JOptionPane.ERROR_MESSAGE);
}

3. 可选优化:修复addCustomer的异常捕获逻辑

当前addCustomer最外层的catch(Exception e)会捕获所有异常并返回错误字符串,你声明的throws UniqueValueException实际无效,上层永远接收不到该异常。如果要让上层能捕获业务异常,需要调整外层catch逻辑放过UniqueValueException:

// 放在原有异常捕获的最前面
catch(UniqueValueException e){
    throw e; // 优先抛出业务异常
}
catch(Exception e) {
    return("\nAn unexpected error occured.");
}

修改完成后,校验到重复值时抛出的异常就能正常传递到上层,不会再执行后续的写入逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 06:06:08