aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniil Fedotov <[email protected]>2019-04-26 16:53:56 -0400
committerDan Gudmundsson <[email protected]>2019-05-07 09:40:07 +0200
commitd63237bd38059b8468ec4e147cca49b1cf8caac4 (patch)
treeb2ac0696d11f81d0f0ef6b7235fe2d9eaaf883e1
parentcc804d6650f81617a4a6fd08617be43cf8aa6c2e (diff)
downloadotp-d63237bd38059b8468ec4e147cca49b1cf8caac4.tar.gz
otp-d63237bd38059b8468ec4e147cca49b1cf8caac4.tar.bz2
otp-d63237bd38059b8468ec4e147cca49b1cf8caac4.zip
Report stacktrace in non-transactions activity function errors.
If an activity function fails with an error, the stacktrace is dropped in non_transaction function try/catch clause. This makes debuging of errors inside a transaction really hard. Transaction activities handle errors and exits differently, non-transaction activities should do the same. Adding the stacktrace to the exit reason when translating errors to exits.
-rw-r--r--lib/mnesia/src/mnesia_tm.erl5
-rw-r--r--lib/mnesia/test/mnesia_dirty_access_test.erl34
2 files changed, 35 insertions, 4 deletions
diff --git a/lib/mnesia/src/mnesia_tm.erl b/lib/mnesia/src/mnesia_tm.erl
index cbf7db28f0..8b79fca1d7 100644
--- a/lib/mnesia/src/mnesia_tm.erl
+++ b/lib/mnesia/src/mnesia_tm.erl
@@ -743,8 +743,9 @@ non_transaction(OldState, Fun, Args, ActivityKind, Mod) ->
{aborted, Reason} -> mnesia:abort(Reason);
Res -> Res
catch
- throw:Throw -> throw(Throw);
- _:Reason -> exit(Reason)
+ throw:Throw -> throw(Throw);
+ error:Reason:ST -> exit({Reason, ST});
+ exit:Reason -> exit(Reason)
after
case OldState of
undefined -> erase(mnesia_activity_state);
diff --git a/lib/mnesia/test/mnesia_dirty_access_test.erl b/lib/mnesia/test/mnesia_dirty_access_test.erl
index 67ef1fe901..984f43582c 100644
--- a/lib/mnesia/test/mnesia_dirty_access_test.erl
+++ b/lib/mnesia/test/mnesia_dirty_access_test.erl
@@ -48,7 +48,7 @@
del_table_copy_1/1, del_table_copy_2/1, del_table_copy_3/1,
add_table_copy_1/1, add_table_copy_2/1, add_table_copy_3/1,
add_table_copy_4/1, move_table_copy_1/1, move_table_copy_2/1,
- move_table_copy_3/1, move_table_copy_4/1]).
+ move_table_copy_3/1, move_table_copy_4/1, dirty_error_stacktrace/1]).
-export([update_trans/3]).
@@ -64,7 +64,7 @@ all() ->
{group, dirty_update_counter}, {group, dirty_delete},
{group, dirty_delete_object},
{group, dirty_match_object}, {group, dirty_index},
- {group, dirty_iter}, {group, admin_tests}].
+ {group, dirty_iter}, {group, admin_tests}, dirty_error_stacktrace].
groups() ->
[{dirty_write, [],
@@ -114,6 +114,36 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Errors in dirty activity should have stacktrace
+dirty_error_stacktrace(Config) ->
+ %% Custom errors should have stacktrace
+ try
+ mnesia:async_dirty(fun() -> error(custom_error) end)
+ catch
+ exit:{custom_error, _} -> ok
+ end,
+
+ %% Undef error should have unknown module and function in the stacktrace
+ try
+ mnesia:async_dirty(fun() -> unknown_module:unknown_fun(arg) end)
+ catch
+ exit:{undef, [{unknown_module, unknown_fun, [arg], []} | _]} -> ok
+ end,
+
+ %% Exists don't have stacktrace
+ try
+ mnesia:async_dirty(fun() -> exit(custom_error) end)
+ catch
+ exit:custom_error -> ok
+ end,
+
+ %% Aborts don't have a stacktrace (unfortunately)
+ try
+ mnesia:async_dirty(fun() -> mnesia:abort(custom_abort) end)
+ catch
+ exit:{aborted, custom_abort} -> ok
+ end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Write records dirty