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

LWC场景下如何在JavaScript Try/Catch中区分Apex API异常类型

LWC调用Apex时可靠识别异常类型的实现方案

你提到的通过headers传入自定义exceptionType判断异常类型的方案是可行的,除此之外还有两种常用的稳定方案,均可以完全避免匹配异常字符串的不稳定问题。

方案1:结构化错误信息 + AuraHandledException

这是Salesforce官方推荐的常规方案,将异常类型和提示信息封装为JSON字符串放在AuraHandledException的消息中,前端捕获后解析即可。

Apex示例代码

public class OrderService {
    @AuraEnabled(cacheable=false)
    public static String processOrder(Id orderId) {
        try {
            // 业务逻辑校验
            if([SELECT Count() FROM Case WHERE OrderId = :orderId] == 0) {
                Map<String, Object> errMap = new Map<String, Object>{
                    'exceptionType' => 'E123',
                    'message' => '处理前订单必须关联对应的工单'
                };
                throw new AuraHandledException(JSON.serialize(errMap));
            }
            // 其他业务逻辑
            return '处理成功';
        } catch(Exception e) {
            if(e instanceof AuraHandledException) {
                throw e;
            }
            // 未知异常返回通用结构
            Map<String, Object> errMap = new Map<String, Object>{
                'exceptionType' => 'E999',
                'message' => '系统内部错误'
            };
            throw new AuraHandledException(JSON.serialize(errMap));
        }
    }
}

LWC前端示例代码

async myFunc() {
    try {
        const response = await myApexMethodCall();
        // 成功逻辑处理
    } catch(err) {
        try {
            // 解析结构化异常信息
            const errInfo = JSON.parse(err.body.message);
            if (errInfo.exceptionType === 'E123') {
                alert(errInfo.message);
            } else {
                alert('接口调用出错,请联系系统管理员');
            }
        } catch(parseErr) {
            // 兼容非结构化异常的兜底处理
            alert('接口调用出错,请联系系统管理员');
        }
    }
}

方案2:自定义响应头传递异常类型(你提到的方案)

该方案直接把异常类型放在响应头中返回,前端无需解析JSON,直接读取头字段即可,注意仅支持cacheable=false的Apex方法,开启缓存的方法无法返回自定义响应头。

Apex示例代码

@AuraEnabled(cacheable=false)
public static String processOrder(Id orderId) {
    if([SELECT Count() FROM Case WHERE OrderId = :orderId] == 0) {
        // 写入自定义响应头
        ApexPages.currentPage().getHeaders().put('exceptionType', 'E123');
        throw new AuraHandledException('处理前订单必须关联对应的工单');
    }
    return '处理成功';
}

LWC前端示例代码

和你给出的代码逻辑完全一致:

async myFunc() {
    try {
        const response = await myApexMethodCall();
    } catch(err) {
        if (err.headers.exceptionType === 'E123') {
            alert('处理前订单必须关联对应的工单');
        } else {
            alert('接口调用出错,请联系系统管理员');
        }
    }
}

方案3:统一响应结构体(无异常抛出)

该方案是稳定性最高的方案,Apex侧不抛出任何异常,而是返回固定格式的响应对象,前端通过返回的状态码判断业务结果,同时支持开启缓存的Apex方法。

Apex示例代码

// 统一响应结构体
public class ApiResponse {
    @AuraEnabled public Integer code; // 0=成功,其他值为错误码
    @AuraEnabled public String message;
    @AuraEnabled public Object data;
}

@AuraEnabled(cacheable=true)
public static ApiResponse processOrder(Id orderId) {
    ApiResponse res = new ApiResponse();
    try {
        if([SELECT Count() FROM Case WHERE OrderId = :orderId] == 0) {
            res.code = 123;
            res.message = '处理前订单必须关联对应的工单';
            return res;
        }
        res.code = 0;
        res.data = '处理成功';
        return res;
    } catch(Exception e) {
        res.code = 999;
        res.message = '系统内部错误';
        return res;
    }
}

LWC前端示例代码

async myFunc() {
    const res = await myApexMethodCall();
    if(res.code === 0) {
        // 成功逻辑处理
        console.log(res.data);
    } else if(res.code === 123) {
        alert(res.message);
    } else {
        alert('接口调用出错,请联系系统管理员');
    }
}

选型建议

  • 若Apex方法需要开启缓存,优先选择方案3
  • 若不需要开启缓存,方案1和方案2均可按需选择,方案1兼容性更强,不需要依赖响应头

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 08:45:03