Skip to content

Commit

Permalink
Merge pull request #51 from paulo-ferraz-oliveira/feature/error-acc
Browse files Browse the repository at this point in the history
Allow accumulating errors instead of displaying them as they happen
  • Loading branch information
onno-vos-dev authored Mar 17, 2023
2 parents fdc2d07 + 43b15b7 commit d923af7
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 15 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,18 @@ Different credential providers may have other settings which you can use to
change their behaviors. See the documentation for each provider for more
details.

Error Logging
-------------

If you prefer to not log errors as they happen (the default behavior), but accumulate
them for later, you can set erlang environment variable `log_errors_immediately` to
`false` as in this example:

```erlang
{aws_credentials, [{log_errors_immediately, false}]
},
```

License and copyright
---------------------
This project is licensed under the terms of the Apache 2 license. It is a
Expand Down
14 changes: 14 additions & 0 deletions src/aws_credentials.erl
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
, make_map/3
, make_map/4
, make_map/5
, log_error/3
]).

-record(state, { credentials = undefined :: map()
Expand Down Expand Up @@ -167,6 +168,13 @@ format_status(_, [_PDict, State]) ->
%% Internal functions
%%====================================================================

-spec log_error(String :: unicode:chardata(), Args :: [term()], logger:metadata()) -> ok.
log_error(String, Args, Metadata) ->
case application:get_env(aws_credentials, log_errors_immediately, true) of
true -> ?LOG_ERROR(String, Args, Metadata);
false -> ?LOG_INFO(String, Args, Metadata)
end.

-spec fetch_credentials(aws_credentials_provider:options()) ->
{ok, credentials() | 'undefined', reference() | 'undefined'}.
fetch_credentials(Options) ->
Expand All @@ -179,6 +187,12 @@ fetch_credentials(Options) ->
?LOG_INFO("No credentials available~n",
[],
#{domain => [aws_credentials]}),
{ok, undefined, setup_callback(?RETRY_DELAY)};
{error, ErrorLog} when is_list(ErrorLog) andalso ShouldCatch ->
?LOG_INFO("No credentials available~n",
[],
#{domain => [aws_credentials]}),
[?LOG_ERROR(String, Args, Metadata) || {String, Args, Metadata} <- ErrorLog],
{ok, undefined, setup_callback(?RETRY_DELAY)}
catch E:R:ST when ShouldCatch ->
?LOG_INFO("aws_credentials ignoring exception ~p:~p (~p)~n",
Expand Down
8 changes: 4 additions & 4 deletions src/aws_credentials_httpc.erl
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ request(Method, URL, RequestHeaders, Tries, Remaining, Errs) ->

Error ->
NewRemaining = Remaining - 1,
?LOG_ERROR("Error fetching URL (attempts left: "
"~p of ~p) ~p: ~p.",
[NewRemaining, Tries, URL, Error],
#{domain => [aws_credentials]}),
String = "Error fetching URL (attempts left: ~p of ~p) ~p: ~p.",
Args = [NewRemaining, Tries, URL, Error],
Metadata = #{domain => [aws_credentials]},
aws_credentials:log_error(String, Args, Metadata),
timer:sleep((Tries - NewRemaining) * ?DELAY),
request(Method, URL, RequestHeaders, Tries, NewRemaining, [ Error | Errs ])
end.
Expand Down
31 changes: 20 additions & 11 deletions src/aws_credentials_provider.erl
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
| aws_credentials_file
| aws_credentials_ecs
| aws_credentials_ec2.
-type error_log_elem() :: {String :: unicode:chardata(), Args :: [term()], logger:metadata()}.
-type error_log() :: [error_log_elem()].
-export_type([ options/0, expiration/0 ]).

-callback fetch(options()) ->
Expand All @@ -49,28 +51,35 @@

-spec fetch() ->
{ok, aws_credentials:credentials(), expiration()} |
{'error', 'no_credentials'}.
{'error', 'no_credentials'} |
{'error', error_log()}.
fetch() ->
fetch(#{}).

-spec fetch(options()) ->
{ok, aws_credentials:credentials(), expiration()} |
{'error', 'no_credentials'}.
{'error', 'no_credentials'} |
{'error', error_log()}.
fetch(Options) ->
Providers = get_env(credential_providers, ?DEFAULT_PROVIDERS),
evaluate_providers(Providers, Options).
evaluate_providers(Providers, Options, []).

-spec evaluate_providers([provider() | {provider(), options()}], options()) ->
-spec evaluate_providers([provider() | {provider(), options()}], options(), error_log()) ->
{ok, aws_credentials:credentials(), expiration()} |
{'error', no_credentials}.
evaluate_providers([], _Options) -> {error, no_credentials};
evaluate_providers([ Provider | Providers ], Options) ->
{'error', no_credentials} |
{'error', error_log()}.
evaluate_providers([], _Options, []) ->
{error, no_credentials};
evaluate_providers([], _Options, Errors) when is_list(Errors) ->
{error, lists:reverse(Errors)};
evaluate_providers([ Provider | Providers ], Options, Errors) ->
case Provider:fetch(Options) of
{error, _} = Error ->
?LOG_ERROR("Provider ~p reports ~p",
[Provider, Error],
#{domain => [aws_credentials]}),
evaluate_providers(Providers, Options);
String = "Provider ~p reports ~p",
Args = [Provider, Error],
Metadata = #{domain => [aws_credentials]},
aws_credentials:log_error(String, Args, Metadata),
evaluate_providers(Providers, Options, [{String, Args, Metadata} | Errors]);
{ok, Credentials, Expiration} ->
{ok, Credentials, Expiration}
end.
Expand Down

0 comments on commit d923af7

Please sign in to comment.