asobi_extension_erase (asobi v0.84.0)

View Source

Runs every installed extension's erase path for one player.

Core's caller holds the transaction; this walks the installed set inside it, calls erase_player/1 on each extension that exports one, and stops at the first failure. See asobi_extension:erase_player/1 for why erasure is atomic across extensions rather than best-effort, and why the alternative to this callback is a cascade in the migration rather than a key in owns/0.

A caller must assert the result, because a bare {error, _} returned from inside asobi_repo:transaction/1 still commits:

asobi_repo:transaction(fun() ->
    ok = asobi_extension_erase:run(PlayerId),
    {ok, _} = asobi_repo:delete_all(...),
    ...
end).

The badmatch is what rolls the transaction back; the line naming the extension is logged here, before the reason is flattened into a badmatch term.

An extension that raises is caught rather than allowed to propagate, so the failure is attributed to a name before it becomes the caller's problem. Nothing runs after a catch: the Postgres transaction is already aborted at that point, and the only correct next statement is the caller's rollback.

Failure reasons carry the shape of what came back - a tag and a size, a truncated formatted reason, the top stack frame without arguments - never the term itself. What an extension returns on this path can be the data subject's personal data, and the reason flows into the log line below and into the caller's badmatch; neither may hold it. asobi_extension_export applies the same rule.

Summary

Functions

ok, or the first extension to fail and why. Nothing is retried and nothing after it is attempted.

Functions

run(PlayerId)

-spec run(binary()) -> ok | {error, {asobi_extension:name(), term()}}.

ok, or the first extension to fail and why. Nothing is retried and nothing after it is attempted.