HG-392 Add accounter unhold in failed withdrawals (#29)

* Add accounter unhold in failed withdrawals
* Add simple error mapping
This commit is contained in:
Andrey Fadeev 2018-11-01 12:33:04 +03:00 committed by GitHub
parent 57fc3b7f30
commit b3e4729dd0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 70 additions and 11 deletions

View File

@ -32,6 +32,7 @@
%% ff_transfer_machine behaviour
-behaviour(ff_transfer_machine).
-export([process_transfer/1]).
-export([process_failure/2]).
%% Accessors
@ -151,6 +152,13 @@ process_transfer(Deposit) ->
Activity = deduce_activity(Deposit),
do_process_transfer(Activity, Deposit).
-spec process_failure(any(), deposit()) ->
{ok, process_result()} |
{error, _Reason}.
process_failure(Reason, Deposit) ->
ff_transfer:process_failure(Reason, Deposit).
%% Internals
-type activity() ::

View File

@ -59,6 +59,7 @@
%% ff_transfer_machine behaviour
-behaviour(ff_transfer_machine).
-export([process_transfer/1]).
-export([process_failure/2]).
%% Event source
@ -153,6 +154,26 @@ create(TransferType, ID, Body, Params) ->
process_transfer(Transfer) ->
process_activity(deduce_activity(Transfer), Transfer).
-spec process_failure(any(), transfer()) ->
{ok, {ff_transfer_machine:action(), [ff_transfer_machine:event(event())]}} |
{error, _Reason}.
process_failure(Reason, Transfer) ->
{ok, ShutdownEvents} = do_process_failure(Reason, Transfer),
{ok, {undefined, ShutdownEvents ++ [{status_changed, {failed, Reason}}]}}.
do_process_failure(_Reason, #{status := pending, p_transfer := #{status := created}}) ->
{ok, []};
do_process_failure(_Reason, #{status := pending, p_transfer := #{status := prepared}} = Transfer) ->
do(fun () ->
unwrap(with(p_transfer, Transfer, fun ff_postings_transfer:cancel/1))
end);
do_process_failure(Reason, #{status := pending, p_transfer := #{status := committed}}) ->
erlang:error({unprocessable_failure, committed_p_transfer, Reason});
do_process_failure(_Reason, Transfer) ->
no_p_transfer = maps:get(p_transfer, Transfer, no_p_transfer),
{ok, []}.
-type activity() ::
prepare_transfer |
commit_transfer |

View File

@ -38,6 +38,10 @@
{ok, {action(), [event(_)]}} |
{error, _Reason}.
-callback process_failure(_Reason, transfer(_)) ->
{ok, {action(), [event(_)]}} |
{error, _Reason}.
-optional_callbacks([process_call/2]).
%% API
@ -151,10 +155,12 @@ process_result({ok, {Action, Events}}, St) ->
events => set_events(Events),
action => set_action(Action, St)
});
process_result({error, Reason}, _St) ->
#{
events => emit_failure(Reason)
}.
process_result({error, Reason}, St) ->
{ok, {Action, Events}} = handler_process_failure(Reason, transfer(St)),
genlib_map:compact(#{
events => set_events(Events),
action => set_action(Action, St)
}).
set_events([]) ->
undefined;
@ -170,8 +176,6 @@ set_action(poll, St) ->
Timeout = erlang:max(1, machinery_time:interval(Now, ff_machine:updated(St)) div 1000),
{set_timer, {timeout, Timeout}}.
emit_failure(Reason) ->
ff_machine:emit_event({status_changed, {failed, Reason}}).
%% Handler convertors
@ -203,4 +207,8 @@ handler_process_call(CallArgs, Transfer) ->
handler_process_transfer(Transfer) ->
Handler = transfer_handler(Transfer),
Handler:process_transfer(Transfer).
Handler:process_transfer(Transfer).
handler_process_failure(Reason, Transfer) ->
Handler = transfer_handler(Transfer),
Handler:process_failure(Reason, Transfer).

View File

@ -32,6 +32,7 @@
%% ff_transfer_machine behaviour
-behaviour(ff_transfer_machine).
-export([process_transfer/1]).
-export([process_failure/2]).
%% Accessors
@ -164,6 +165,13 @@ process_transfer(Withdrawal) ->
Activity = deduce_activity(Withdrawal),
do_process_transfer(Activity, Withdrawal).
-spec process_failure(any(), withdrawal()) ->
{ok, process_result()} |
{error, _Reason}.
process_failure(Reason, Withdrawal) ->
ff_transfer:process_failure(Reason, Withdrawal).
%% Internals
-type activity() ::

View File

@ -289,7 +289,8 @@ create_wallet(IdentityID, Name, Currency, _C) ->
),
ID.
await_wallet_balance(Balance, ID) ->
await_wallet_balance({Amount, Currency}, ID) ->
Balance = {Amount, {{inclusive, Amount}, {inclusive, Amount}}, Currency},
Balance = ct_helper:await(
Balance,
fun () -> get_wallet_balance(ID) end,
@ -297,7 +298,8 @@ await_wallet_balance(Balance, ID) ->
),
ok.
await_destination_balance(Balance, ID) ->
await_destination_balance({Amount, Currency}, ID) ->
Balance = {Amount, {{inclusive, Amount}, {inclusive, Amount}}, Currency},
Balance = ct_helper:await(
Balance,
fun () -> get_destination_balance(ID) end,
@ -315,7 +317,7 @@ get_destination_balance(ID) ->
get_account_balance(Account) ->
{ok, {Amounts, Currency}} = ff_transaction:balance(ff_account:accounter_account_id(Account)),
{ff_indef:current(Amounts), Currency}.
{ff_indef:current(Amounts), ff_indef:to_range(Amounts), Currency}.
create_instrument(Type, IdentityID, Name, Currency, Resource, C) ->
ID = genlib:unique(),

View File

@ -750,7 +750,7 @@ to_swag(withdrawal_status, {failed, Failure}) ->
to_swag(withdrawal_status_failure, Failure = #domain_Failure{}) ->
to_swag(domain_failure, Failure);
to_swag(withdrawal_status_failure, Failure) ->
genlib:to_binary(Failure);
to_swag(domain_failure, map_internal_error(Failure));
to_swag(withdrawal_event, {EventId, Ts, {status_changed, Status}}) ->
to_swag(map, #{
<<"eventID">> => EventId,
@ -787,3 +787,15 @@ to_swag(map, Map) ->
genlib_map:compact(Map);
to_swag(_, V) ->
V.
map_internal_error({wallet_limit, {terms_violation, {cash_range, _Details}}}) ->
#domain_Failure{
code = <<"terms_violation">>,
sub = #domain_SubFailure{
code = <<"cash_range">>
}
};
map_internal_error(_Reason) ->
#domain_Failure{
code = <<"failed">>
}.