I don't know about the proposed solution (the onerror
part of the question). This answer deals differently with the original problem.
At the very least, the original action can maintain a flag in the RAM, and the deferred one can clear that flag upon completion.
It might naturally be more than just a flag, depending on what you want it to do.
A practical example is eosio.system
with its name bidding feature.
A bid event should return EOS to the previous bidder.
Instead of just sending EOS (which would be a vulnerability), it makes a record in the refunds_table
, and then tries to send a deferred transaction with bidrefund
action.
The bidrefund
action transfers the EOS and clears the refunds_table
entry.
In case the deferred transaction fails for any reason, the bidrefund
action can be called again anytime, without the eosio.system
contract's permission.
The code can be found here.