[thrift] gut Erlang exception handling
Summary: * move type field to tException from subclasses
* add backtrace to tException
* add oop:is_a
* on exit, wrap exceptions in {thrift_exception, E} ... otherwise can't distinguish e.g. exit:{{tBinProtException, {tException, ...}}, Stack} vs. exit:{tBinProtException, {tException, ...} -- I hate erlang
* all throws/exits to tException:throw which does the wrapping described above
Reviewed By: eletuchy
Test Plan: been using this code on my live server ^_^
Revert: OK
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665350 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/erl/src/oop.erl b/lib/erl/src/oop.erl
index e4de147..418f0f2 100644
--- a/lib/erl/src/oop.erl
+++ b/lib/erl/src/oop.erl
@@ -14,7 +14,7 @@
-module(oop).
--export([start_new/2, get/2, set/3, call/2, call/3, inspect/1, class/1, is_object/1]).
+-export([start_new/2, get/2, set/3, call/2, call/3, inspect/1, class/1, is_object/1, is_a/2]).
-export([call1/3]). %% only for thrift_oop_server ... don't use it
-export([behaviour_info/1]).
@@ -65,7 +65,7 @@
{ok, V} -> V;
undef ->
case get_superobject(Obj) of
- { ok, Superobj } ->
+ {ok, Superobj} ->
Superobj1 = set(Superobj, Field, Value),
Module:attr(Obj, set, super, Superobj1);
undef ->
@@ -180,11 +180,30 @@
class(Obj) when is_tuple(Obj) ->
%% if it's an object its first element will be a class name, and it'll have super/0
case apply_if_defined(?CLASS(Obj), super, []) of
- {ok, V} -> V;
+ {ok, _} -> ?CLASS(Obj);
undef -> none
end;
class(_) -> none.
+%% is_a relationship
+is_a(Obj, Class) ->
+ %% ?INFO("is_a ~p ~p", [Obj, Class]),
+ case is_object(Obj) of
+ true ->
+ is_a1(Obj, Class);
+ false ->
+ false
+ end.
+is_a1(Obj, Class) when Class == ?CLASS(Obj) ->
+ true;
+is_a1(Obj, Class) ->
+ case get_superobject(Obj) of
+ undef ->
+ false;
+ {ok, SuperObj} ->
+ is_a1(SuperObj, Class)
+ end.
+
%% is the tuple/record an object?
%% is_object(Obj) = bool()
is_object(Obj) when is_tuple(Obj) ->
@@ -209,7 +228,7 @@
%% io:format("apply ~p ~p ~p~n", [M,F,A]),
{ok, apply(M, F, A)}
catch
- error:Kind when Kind == undef; Kind == function_clause ->
+ _:Kind when Kind == undef; Kind == function_clause ->
case erlang:get_stacktrace() of
%% the first stack call should match MFA when `apply' fails because the function is undefined
%% they won't match if the function is currently running and an error happens in the middle