@@ -92,7 +92,9 @@ handle_info({listen}, #{stream_uri := Uri} = State) ->
9292handle_info ({'DOWN' , _Mref , process , ShotgunPid , Reason }, #{conn := ShotgunPid , backoff := Backoff } = State ) ->
9393 NewBackoff = ldclient_backoff :fail (Backoff ),
9494 _ = ldclient_backoff :fire (NewBackoff ),
95- error_logger :warning_msg (" Got DOWN message from shotgun pid with reason: ~p , will retry in ~p ms~n " , [Reason , maps :get (current , NewBackoff )]),
95+ % Reason from DOWN message could contain connection details with headers/SDK keys
96+ SafeReason = ldclient_key_redaction :format_shotgun_error (Reason ),
97+ error_logger :warning_msg (" Got DOWN message from shotgun pid with reason: ~s , will retry in ~p ms~n " , [SafeReason , maps :get (current , NewBackoff )]),
9698 {noreply , State #{conn := undefined , backoff := NewBackoff }};
9799handle_info ({timeout , _TimerRef , listen }, State ) ->
98100 error_logger :info_msg (" Reconnecting streaming connection...~n " ),
@@ -132,13 +134,16 @@ do_listen(#{
132134 NewBackoff = do_listen_fail_backoff (Backoff , temporary , Reason ),
133135 State #{backoff := NewBackoff };
134136 {error , permanent , Reason } ->
137+ % Reason here is already safe: either a sanitized string from format_shotgun_error
138+ % or an integer status code from the do_listen/5 method.
135139 error_logger :error_msg (" Stream encountered permanent error ~p , giving up~n " , [Reason ]),
136140 State ;
137141 {ok , Pid } ->
138142 NewBackoff = ldclient_backoff :succeed (Backoff ),
139143 State #{conn := Pid , backoff := NewBackoff }
140- catch Code :Reason ->
141- NewBackoff = do_listen_fail_backoff (Backoff , Code , Reason ),
144+ catch Code :_Reason ->
145+ % Don't pass raw exception reason as it could contain unsafe data
146+ NewBackoff = do_listen_fail_backoff (Backoff , Code , " unexpected exception" ),
142147 State #{backoff := NewBackoff }
143148 end .
144149
@@ -171,9 +176,10 @@ do_listen(Uri, FeatureStore, Tag, GunOpts, Headers) ->
171176 F = fun (nofin , _Ref , Bin ) ->
172177 try
173178 process_event (parse_shotgun_event (Bin ), FeatureStore , Tag )
174- catch Code :Reason ->
175- % Exception when processing event, log error, close connection
176- error_logger :warning_msg (" Invalid SSE event error (~p ): ~p " , [Code , Reason ]),
179+ catch Code :_Reason ->
180+ % Exception when processing event - don't log exception details
181+ % as they could theoretically contain sensitive data
182+ error_logger :warning_msg (" Invalid SSE event error (~p )" , [Code ]),
177183 shotgun :close (Pid )
178184 end ;
179185 (fin , _Ref , _Bin ) ->
@@ -185,7 +191,8 @@ do_listen(Uri, FeatureStore, Tag, GunOpts, Headers) ->
185191 case shotgun :get (Pid , Path ++ Query , Headers , Options ) of
186192 {error , Reason } ->
187193 shotgun :close (Pid ),
188- {error , temporary , Reason };
194+ SafeReason = ldclient_key_redaction :format_shotgun_error (Reason ),
195+ {error , temporary , SafeReason };
189196 {ok , #{status_code := StatusCode }} when StatusCode >= 400 ->
190197 {error , ldclient_http :is_http_error_code_recoverable (StatusCode ), StatusCode };
191198 {ok , _Ref } ->
0 commit comments