@@ -38,13 +38,13 @@ defmodule Sentry.Client do
3838
3939 require Logger
4040
41- @ type get_dsn :: { String . t , String . t , Integer . t }
41+ @ type get_dsn :: { String . t ( ) , String . t ( ) , Integer . t ( ) }
4242 @ sentry_version 5
4343 @ max_attempts 4
4444 @ hackney_pool_name :sentry_pool
4545
4646 quote do
47- unquote ( @ sentry_client "sentry-elixir/#{ Mix.Project . config [ :version ] } " )
47+ unquote ( @ sentry_client "sentry-elixir/#{ Mix.Project . config ( ) [ :version ] } " )
4848 end
4949
5050 @ doc """
@@ -56,7 +56,7 @@ defmodule Sentry.Client do
5656 * `:result` - Allows specifying how the result should be returned. Options include `:sync`, `:none`, and `:async`. `:sync` will make the API call synchronously, and return `{:ok, event_id}` if successful. `:none` sends the event from an unlinked child process under `Sentry.TaskSupervisor` and will return `{:ok, ""}` regardless of the result. `:async` will start an unlinked task and return a tuple of `{:ok, Task.t}` on success where the Task can be awaited upon to receive the result asynchronously. When used in an OTP behaviour like GenServer, the task will send a message that needs to be matched with `GenServer.handle_info/2`. See `Task.Supervisor.async_nolink/2` for more information. `:async` is the default.
5757 * `:sample_rate` - The sampling factor to apply to events. A value of 0.0 will deny sending any events, and a value of 1.0 will send 100% of events.
5858 """
59- @ spec send_event ( Event . t ) :: { :ok , Task . t | String . t } | :error | :unsampled
59+ @ spec send_event ( Event . t ( ) ) :: { :ok , Task . t ( ) | String . t ( ) } | :error | :unsampled
6060 def send_event ( % Event { } = event , opts \\ [ ] ) do
6161 result = Keyword . get ( opts , :result , :async )
6262 sample_rate = Keyword . get ( opts , :sample_rate ) || Config . sample_rate ( )
@@ -76,6 +76,7 @@ defmodule Sentry.Client do
7676 |> case do
7777 { :ok , body } ->
7878 do_send_event ( event , body , result )
79+
7980 { :error , error } ->
8081 log_api_error ( "Unable to encode Sentry error - #{ inspect ( error ) } " )
8182 :error
@@ -85,22 +86,26 @@ defmodule Sentry.Client do
8586 defp do_send_event ( event , body , :async ) do
8687 { endpoint , public_key , secret_key } = get_dsn! ( )
8788 auth_headers = authorization_headers ( public_key , secret_key )
88- { :ok , Task.Supervisor . async_nolink ( Sentry.TaskSupervisor , fn ->
89- try_request ( :post , endpoint , auth_headers , body )
90- |> maybe_call_after_send_event ( event )
91- end ) }
89+
90+ { :ok ,
91+ Task.Supervisor . async_nolink ( Sentry.TaskSupervisor , fn ->
92+ try_request ( :post , endpoint , auth_headers , body )
93+ |> maybe_call_after_send_event ( event )
94+ end ) }
9295 end
9396
9497 defp do_send_event ( event , body , :sync ) do
9598 { endpoint , public_key , secret_key } = get_dsn! ( )
9699 auth_headers = authorization_headers ( public_key , secret_key )
100+
97101 try_request ( :post , endpoint , auth_headers , body )
98102 |> maybe_call_after_send_event ( event )
99103 end
100104
101105 defp do_send_event ( event , body , :none ) do
102106 { endpoint , public_key , secret_key } = get_dsn! ( )
103107 auth_headers = authorization_headers ( public_key , secret_key )
108+
104109 Task.Supervisor . start_child ( Sentry.TaskSupervisor , fn ->
105110 try_request ( :post , endpoint , auth_headers , body )
106111 |> maybe_call_after_send_event ( event )
@@ -110,11 +115,16 @@ defmodule Sentry.Client do
110115 end
111116
112117 defp try_request ( method , url , headers , body , current_attempt \\ 1 )
118+
113119 defp try_request ( _ , _ , _ , _ , current_attempt )
114- when current_attempt > @ max_attempts , do: :error
120+ when current_attempt > @ max_attempts ,
121+ do: :error
122+
115123 defp try_request ( method , url , headers , body , current_attempt ) do
116124 case request ( method , url , headers , body ) do
117- { :ok , id } -> { :ok , id }
125+ { :ok , id } ->
126+ { :ok , id }
127+
118128 _ ->
119129 sleep ( current_attempt )
120130 try_request ( method , url , headers , body , current_attempt + 1 )
@@ -127,8 +137,10 @@ defmodule Sentry.Client do
127137 Hackney options can be set via the `hackney_opts` configuration option.
128138 """
129139 def request ( method , url , headers , body ) do
130- hackney_opts = Config . hackney_opts ( )
131- |> Keyword . put_new ( :pool , @ hackney_pool_name )
140+ hackney_opts =
141+ Config . hackney_opts ( )
142+ |> Keyword . put_new ( :pool , @ hackney_pool_name )
143+
132144 with { :ok , 200 , _ , client } <- :hackney . request ( method , url , headers , body , hackney_opts ) ,
133145 { :ok , body } <- :hackney . body ( client ) ,
134146 { :ok , json } <- Poison . decode ( body ) do
@@ -139,6 +151,7 @@ defmodule Sentry.Client do
139151 error_header = :proplists . get_value ( "X-Sentry-Error" , headers , "" )
140152 log_api_error ( "#{ body } \n Received #{ status } from Sentry server: #{ error_header } " )
141153 :error
154+
142155 e ->
143156 log_api_error ( "#{ inspect ( e ) } \n #{ body } " )
144157 :error
@@ -148,19 +161,23 @@ defmodule Sentry.Client do
148161 @ doc """
149162 Generates a Sentry API authorization header.
150163 """
151- @ spec authorization_header ( String . t , String . t ) :: String . t
164+ @ spec authorization_header ( String . t ( ) , String . t ( ) ) :: String . t ( )
152165 def authorization_header ( public_key , secret_key ) do
153166 timestamp = Util . unix_timestamp ( )
167+
154168 data = [
155169 sentry_version: @ sentry_version ,
156170 sentry_client: @ sentry_client ,
157171 sentry_timestamp: timestamp ,
158172 sentry_key: public_key ,
159173 sentry_secret: secret_key
160174 ]
161- query = data
162- |> Enum . map ( fn { name , value } -> "#{ name } =#{ value } " end )
163- |> Enum . join ( ", " )
175+
176+ query =
177+ data
178+ |> Enum . map ( fn { name , value } -> "#{ name } =#{ value } " end )
179+ |> Enum . join ( ", " )
180+
164181 "Sentry " <> query
165182 end
166183
@@ -177,7 +194,9 @@ defmodule Sentry.Client do
177194 @ spec get_dsn! :: get_dsn
178195 def get_dsn! do
179196 # {PROTOCOL}://{PUBLIC_KEY}:{SECRET_KEY}@{HOST}/{PATH}{PROJECT_ID}
180- % URI { userinfo: userinfo , host: host , port: port , path: path , scheme: protocol } = URI . parse ( Config . dsn ( ) )
197+ % URI { userinfo: userinfo , host: host , port: port , path: path , scheme: protocol } =
198+ URI . parse ( Config . dsn ( ) )
199+
181200 [ public_key , secret_key ] = String . split ( userinfo , ":" , parts: 2 )
182201 [ _ , binary_project_id ] = String . split ( path , "/" )
183202 project_id = String . to_integer ( binary_project_id )
@@ -190,27 +209,36 @@ defmodule Sentry.Client do
190209 case Config . after_send_event ( ) do
191210 function when is_function ( function , 2 ) ->
192211 function . ( event , result )
212+
193213 { module , function } ->
194214 apply ( module , function , [ event , result ] )
215+
195216 nil ->
196217 nil
218+
197219 _ ->
198- raise ArgumentError , message: ":after_send_event must be an anonymous function or a {Module, Function} tuple"
220+ raise ArgumentError ,
221+ message: ":after_send_event must be an anonymous function or a {Module, Function} tuple"
199222 end
200223
201224 result
202225 end
203226
204227 def maybe_call_before_send_event ( event ) do
205- case Config . before_send_event do
228+ case Config . before_send_event ( ) do
206229 function when is_function ( function , 1 ) ->
207230 function . ( event )
231+
208232 { module , function } ->
209233 apply ( module , function , [ event ] )
234+
210235 nil ->
211236 event
237+
212238 _ ->
213- raise ArgumentError , message: ":before_send_event must be an anonymous function or a {Module, Function} tuple"
239+ raise ArgumentError ,
240+ message:
241+ ":before_send_event must be an anonymous function or a {Module, Function} tuple"
214242 end
215243 end
216244
@@ -226,7 +254,7 @@ defmodule Sentry.Client do
226254 be included in the JSON body.
227255 """
228256 def render_event ( % Event { } = event ) do
229- map = % {
257+ map = % {
230258 event_id: event . event_id ,
231259 culprit: event . culprit ,
232260 timestamp: event . timestamp ,
@@ -243,12 +271,13 @@ defmodule Sentry.Client do
243271 user: event . user ,
244272 breadcrumbs: event . breadcrumbs ,
245273 fingerprint: event . fingerprint ,
246- modules: event . modules ,
274+ modules: event . modules
247275 }
248276
249277 case event . stacktrace do
250278 % { frames: [ _ | _ ] } ->
251279 Map . put ( map , :stacktrace , event . stacktrace )
280+
252281 _ ->
253282 map
254283 end
@@ -272,7 +301,8 @@ defmodule Sentry.Client do
272301 defp sample_event? ( 1.0 ) , do: true
273302 defp sample_event? ( 0 ) , do: false
274303 defp sample_event? ( 0.0 ) , do: false
304+
275305 defp sample_event? ( sample_rate ) do
276- :rand . uniform < sample_rate
306+ :rand . uniform ( ) < sample_rate
277307 end
278308end
0 commit comments