| %%% Copyright (c) 2007- Facebook | 
 | %%% Distributed under the Thrift Software License | 
 | %%% | 
 | %%% See accompanying file LICENSE or visit the Thrift site at: | 
 | %%% http://developers.facebook.com/thrift/ | 
 |  | 
 | -module(tException). | 
 |  | 
 | -include("oop.hrl"). | 
 | -include("thrift.hrl"). | 
 | -include("tException.hrl"). | 
 |  | 
 | -behavior(oop). | 
 |  | 
 | -export([attr/4, super/0, inspect/1]). | 
 |  | 
 | -export([new/2, add_backtrace_element/2, throw/2, inspect_with_backtrace/2, inspect_with_backtrace/3]). | 
 |  | 
 | -export([read/1]). | 
 |  | 
 | %%% | 
 | %%% define attributes | 
 | %%% 'super' is required unless ?MODULE is a base class | 
 | %%% | 
 |  | 
 | ?DEFINE_ATTR(message); | 
 | ?DEFINE_ATTR(type); | 
 | ?DEFINE_ATTR(backtrace). | 
 |  | 
 | %%% | 
 | %%% behavior callbacks | 
 | %%% | 
 |  | 
 | %%% super() -> SuperModule = atom() | 
 | %%%             |  none | 
 |  | 
 | super() -> | 
 |     none. | 
 |  | 
 | %%% inspect(This) -> string() | 
 |  | 
 | inspect(This) -> | 
 |     BT = ?ATTR(backtrace), | 
 |     Depth = | 
 |         if | 
 |             is_list(BT) -> integer_to_list(length(BT)); | 
 |             true -> "?" | 
 |         end, | 
 |     ?FORMAT_ATTR(message) ++ ", " ++ | 
 |     ?FORMAT_ATTR(type)    ++ ", " | 
 |         " backtrace:" ++ Depth. | 
 |  | 
 | %%% | 
 | %%% class methods | 
 | %%% | 
 |  | 
 | new(Type, Message) -> | 
 |     #?MODULE{type=Type, message=Message, backtrace=[]}. | 
 |  | 
 | add_backtrace_element(E, Info) -> | 
 |     BT = oop:get(E, backtrace), | 
 |     E1 = oop:set(E, backtrace, [Info|BT]), | 
 |     E1. | 
 |  | 
 | throw(Class, Args) -> | 
 |     E = apply(Class, new, Args), | 
 |     exit({thrift_exception, E}). | 
 |  | 
 |  | 
 | inspect_with_backtrace(E, Where, Info) -> | 
 |     E1 = add_backtrace_element(E, Info), | 
 |     inspect_with_backtrace(E1, Where). | 
 |  | 
 | inspect_with_backtrace(E, Where) -> | 
 |     thrift_utils:sformat("** ~s~n** ~s", [Where, oop:inspect(E)]) ++ | 
 |         case oop:get(E, backtrace) of | 
 |             [] -> | 
 |                 ""; | 
 |             BT when is_list(BT) -> | 
 |                 thrift_utils:sformat("~n** trace = ~p", [lists:reverse(BT)]); | 
 |             Else -> | 
 |                 thrift_utils:sformat("<ERROR BT NOT A LIST = ~p>", [Else]) | 
 |         end. | 
 |  | 
 | read(E) -> | 
 |     case oop:class(E) of | 
 |         none -> | 
 |             none; | 
 |         Class -> | 
 |             Type = oop:get(E, type), | 
 |             BT   = oop:get(E, backtrace), | 
 |             {Class, Type, BT} | 
 |     end. |