如何在Beckhoff TwinCAT 3中抛出异常?(断言类函数实现场景)
在TwinCAT 3中实现带日志的Assert式守卫函数(抛出异常逻辑)
我在使用Beckhoff TwinCAT 3的面向对象编程特性时,想实现一个类似Assert的守卫函数:当输入的Condition条件不成立时,先通过ADSLOGDINT记录错误日志,再抛出异常。现有代码如下,请问如何实现抛出异常的逻辑?
FUNCTION GuardI VAR_INPUT Condition : BOOL; Format : T_MaxString; Value : INT; END_VAR IF (NOT Condition) THEN ADSLOGDINT( msgCtrlMask := ADSLOG_MSGTYPE_ERROR OR ADSLOG_MSGTYPE_LOG, msgFmtStr := Format, dintArg := Value); // throw exception here END_IF
实现抛出异常的步骤
在TwinCAT 3中,你可以通过Raise指令抛出异常,结合自定义异常类型或系统预定义异常类型来实现需求:
1. (可选)定义自定义异常类型
如果需要区分特定的守卫异常,可在全局范围内定义自定义异常结构体:
TYPE E_GuardException : STRUCT ErrorCode : UDINT; ErrorMessage : T_MaxString; END_STRUCT END_TYPE
2. 修改Guard函数添加抛出逻辑
使用Raise指令抛出异常,有两种常见实现方式:
方式一:抛出系统预定义异常
直接使用TwinCAT自带的异常类型(如E_AdsException),无需自定义:
FUNCTION GuardI VAR_INPUT Condition : BOOL; Format : T_MaxString; Value : INT; END_VAR IF (NOT Condition) THEN ADSLOGDINT( msgCtrlMask := ADSLOG_MSGTYPE_ERROR OR ADSLOG_MSGTYPE_LOG, msgFmtStr := Format, dintArg := Value); // 抛出系统ADS异常,指定自定义错误码(可按需调整) Raise(E_AdsException(16#00000001)); END_IF
方式二:抛出自定义异常
使用之前定义的自定义异常类型,携带更详细的错误信息:
FUNCTION GuardI VAR_INPUT Condition : BOOL; Format : T_MaxString; Value : INT; END_VAR VAR guardException : E_GuardException; END_VAR IF (NOT Condition) THEN ADSLOGDINT( msgCtrlMask := ADSLOG_MSGTYPE_ERROR OR ADSLOG_MSGTYPE_LOG, msgFmtStr := Format, dintArg := Value); // 初始化自定义异常内容 guardException.ErrorCode := 16#80000001; guardException.ErrorMessage := Format; // 抛出自定义异常 Raise(guardException); END_IF
3. 调用方捕获处理异常
在调用GuardI的代码中,需要用TRY...CATCH块捕获并处理异常:
METHOD SomeMethod VAR inputValue : INT := 0; END_VAR TRY // 调用守卫函数,当inputValue <=0时触发异常 GuardI(Condition := inputValue > 0, Format := 'Input value must be greater than 0, got %d', Value := inputValue); // 正常业务逻辑 // ... CATCH // 获取并处理异常详情 // 可通过GetException()函数获取异常对象 END_CATCH
关键说明
Raise指令必须传入结构体类型的异常对象,符合TwinCAT的异常规范- 系统预定义异常类型可直接使用,适合简单场景
- 自定义异常可携带更多业务相关的错误信息,便于问题排查
内容的提问来源于stack exchange,提问作者florians
相关产品推荐
相关产品推荐

