10. CORBA系统和用户定义的异常 | 10. CORBA System and User Defined Exceptions
10 CORBA系统和用户定义的例外
10.1系统异常
Orber或任何其他ORB可能引发系统异常。 这些例外包含状态和次要字段,并且可能不会出现在操作引发异常IDL定义中。
状态字段
状态字段指示请求是否完成,并且将被分配以下Erlang原子之一:
状态 | 描述 |
---|---|
'COMPLETED_YES' | 该操作在目标对象上被调用,但在对象回答后发生错误。例如,如果服务器回复但Orber无法封送并将回复发送给客户端ORB,则会发生这种情况。 |
'COMPLETED_NO' | Orber未能调用目标对象上的操作。例如,如果对象不再存在,就会发生这种情况。 |
'COMPLETED_MAYBE' | Orber调用目标对象上的操作,但发生错误,无法确定请求是否真的到达对象。 |
次要字段
次要字段包含一个整数(VMCID),这与调用失败的更具体原因有关。该函数orber:exception_info/1
可用于将次要代码映射到字符串。请注意,对于未被OMG或Orber分配的VMCID:,必须查阅该特定ORB的文档。
支持的系统异常
OMGCORBA规范定义了以下异常:
'BAD_CONTEXT'
- 如果请求不包含正确的上下文,则引发此异常。
'BAD_INV_ORDER'
- 此异常表示操作已按错误顺序调用操作,这会导致例如死锁。
'BAD_OPERATION'
- 如果目标对象存在,则引发,但被调用的操作不受支持。
'BAD_PARAM'
- 例如,如果参数超出范围或被认为是非法的,则抛出该错误。
'BAD_TYPECODE'
- 如果传递了非法类型代码,例如封装在任何数据类型中,'BAD_TYPECODE'
则会引发异常。
'BAD_QOS'
- 只要对象无法支持所需的服务质量就会引发。
'CODESET_INCOMPATIBLE'
- 如果由于例如char
和/或的不同表示而导致两个ORB无法通信,则引发'CODESET_INCOMPATIBLE'
wchar
。
'COMM_FAILURE'
- 如果ORB无法建立通信或在操作正在进行时丢失,则引发此错误。
'DATA_CONVERSION'
- 如果ORB无法将接收到的数据转换为本机表示,则产生'DATA_CONVERSION'
。另见'CODESET_INCOMPATIBLE'
例外。
'FREE_MEM'
- ORB未能释放动态内存并失败。
'IMP_LIMIT'
- 运行时在ORB中超出了实施限制。例如,对象工厂可能会限制允许创建的对象客户端的数量。
'INTERNAL'
- ORB内部发生故障,无法识别。您可以考虑联系ORB提供商的支持。
'INTF_REPOS'
- ORB无法访问接口存储库,或检测到与接口存储库有关的其他故障。
'INITIALIZE'
- ORB初始化失败,例如,由于网络或配置错误。
'INVALID_TRANSACTION'
- 如果请求携带无效的事务上下文,则引发。
'INV_FLAG'
- 一个无效标志被传递给一个操作,例如导致连接关闭。
'INV_IDENT'
- 此异常表示IDL标识符不正确。
'INV_OBJREF'
- 如果对象引用格式错误或引用为零(参见corba:create_nil_objref / 0),则会引发此异常。
'INV_POLICY'
- 由于适用于特定调用的策略覆盖之间不兼容,无法进行调用。
'MARSHAL'
- 当ORB无法编组/解组请求或回复时,客户端或服务器端可能会提出此异常。
'NO_IMPLEMENT'
- 如果操作存在但没有实现存在,则引发此异常。
'NO_MEMORY'
- ORB内存不足。
'NO_PERMISSION'
- 呼叫者没有足够的权限,例如SSL
证书不正确。
'NO_RESOURCES'
- 超出了一般平台资源限制。
'NO_RESPONSE'
- 没有可用的延迟同步请求响应。
'OBJ_ADAPTER'
- 表示管理不匹配; 对象适配器无法将对象与实现存储库相关联。
'OBJECT_NOT_EXIST'
- 对象已被处置或终止; 客户端应该删除对象引用的所有副本并启动所需的恢复过程。
'PERSIST_STORE'
- ORB无法建立与其持久存储的连接,或存储中包含的数据已损坏。
'REBIND'
- 一个请求导致,例如,一条'LOCATION_FORWARD'
消息; 如果政策不兼容,则会引发此例外情况。
'TIMEOUT'
- 如果请求在给定的时间限制内未能完成则产生。
'TRANSACTION_MODE'
- 检测到交易策略不匹配。
'TRANSACTION_REQUIRED'
- 被调用的操作需要一个事务,但该请求不包含事务上下文。
'TRANSACTION_ROLLEDBACK'
- 与请求相关的事务已经回滚或将会。
'TRANSACTION_UNAVAILABLE'
- 由于ORB无法联系事务服务,因此无法提供事务上下文。
'TRANSIENT'
- ORB无法确定对象的当前状态,因为无法到达。错误可能是暂时的。
'UNKNOWN'
- 如果实现抛出一个非CORBA或无法识别的异常,则抛出该错误。
10.2 用户定义的例外
用户异常在IDL文件中定义,并在操作中列出引发异常列表。例如,如果我们有以下IDL代码:
module MyModule {
exception MyException {};
exception MyExceptionMsg { string ExtraInfo; };
interface MyInterface {
void foo()
raises(MyException
void bar()
raises(MyException, MyExceptionMsg
void baz(
};
};
10.3 抛出异常
为了能够引发MyException或MyExceptionMsg异常,必须包含生成的MyModule.hrl,其典型用法是:
-module('MyModule_MyInterface_impl').
-include("MyModule.hrl").
bar(State) ->
case TestingSomething of
ok ->
{reply, ok, State};
{error, Reason} when list(Reason) ->
corba:raise(#'MyModule_MyExceptionMsg'{'ExtraInfo' = Reason}
error ->
corba:raise(#'MyModule_MyException'{})
end.
10.4捕获异常
根据我们调用的操作必须能够处理:
- foo -
MyException
或者系统异常。
- bar-
MyException
,MyExceptionMsg
或系统异常。
- 系统异常。
捕获和匹配异常可以以不同的方式完成:
case catch 'MyModule_MyInterface':bar(MIReference) of
ok ->
%% The operation raised no exception.
ok;
{'EXCEPTION', #'MyModule_MyExceptionMsg'{'ExtraInfo' = Reason}} ->
%% If we want to log the Reason we must extract 'ExtraInfo'.
error_logger:error_msg("Operation 'bar' raised: ~p~n", [Reason]),
... do something ...;
{'EXCEPTION', E} when record(E, 'OBJECT_NOT_EXIST') ->
... do something ...;
{'EXCEPTION', E} ->
... do something ...
end.