@@ -135,61 +135,129 @@ defmodule Sentry.Event do
135135 |> Map . drop ( [ :original_exception , :source ] )
136136 end
137137
138- @ doc """
139- Creates an event struct out of collected context and options.
140-
141- > #### Merging Options with Context and Config {: .info}
142- >
143- > Some of the options documented below are **merged** with the Sentry context, or
144- > with the Sentry context *and* the configuration. The option you pass here always
145- > has higher precedence, followed by the context and finally by the configuration.
146- >
147- > See also `Sentry.Context` for information on the Sentry context and `Sentry` for
148- > information on configuration.
149-
150- ## Options
151-
152- * `:exception` - an `t:Exception.t/0`. This is the exception that gets reported in the
138+ create_event_opts_schema = [
139+ exception: [
140+ type: { :custom , __MODULE__ , :__validate_exception__ , [ :exception ] } ,
141+ type_doc: "`t:Exception.t/0`" ,
142+ doc: """
143+ This is the exception that gets reported in the
153144 `:exception` field of `t:t/0`. The term passed here also ends up unchanged in the
154145 `:original_exception` field of `t:t/0`. This option is **required** unless the
155- `:message` option is present. This is not present by default.
156-
157- * `:stacktrace` - a stacktrace, as in `t:Exception.stacktrace/0`. This is not present
158- by default.
159-
160- * `:message` - a message (`t:String.t/0`). This is not present by default.
161-
162- * `:extra` - map of extra context, which gets merged with the current context
146+ `:message` option is present. Not present by default.
147+ """
148+ ] ,
149+ stacktrace: [
150+ type: { :list , :any } ,
151+ type_doc: "`t:Exception.stacktrace/0`" ,
152+ doc: """
153+ The exception's stacktrace. This can also be used with messages (`:message`). Not
154+ present by default.
155+ """
156+ ] ,
157+ message: [
158+ type: :string ,
159+ doc: """
160+ A message to report. The string can contain interpolation markers (`%s`). In that
161+ case, you can pass the `:interpolation_parameters` option as well to fill
162+ in those parameters. See `Sentry.capture_message/2` for more information on
163+ message interpolation. Not present by default.
164+ """
165+ ] ,
166+ extra: [
167+ type: { :map , { :or , [ :atom , :string ] } , :any } ,
168+ type_doc: "`t:Sentry.Context.extra/0`" ,
169+ default: % { } ,
170+ doc: """
171+ Map of extra context, which gets merged with the current context
163172 (see `Sentry.Context.set_extra_context/1`). If fields collide, the ones
164173 in the map passed through this option have precedence over the ones in
165- the context. Defaults to `%{}`.
166-
167- * `:user` - map of user context, which gets merged with the current context
174+ the context.
175+ """
176+ ] ,
177+ user: [
178+ type: :map ,
179+ type_doc: "`t:Sentry.Context.user_context/0`" ,
180+ default: % { } ,
181+ doc: """
182+ Map of user context, which gets merged with the current context
168183 (see `Sentry.Context.set_user_context/1`). If fields collide, the ones
169184 in the map passed through this option have precedence over the ones in
170- the context. Defaults to `%{}`.
171-
172- * `:tags` - map of tags context, which gets merged with the current context (see
185+ the context.
186+ """
187+ ] ,
188+ tags: [
189+ type: { :map , { :or , [ :atom , :string ] } , :any } ,
190+ type_doc: "`t:Sentry.Context.tags/0`" ,
191+ default: % { } ,
192+ doc: """
193+ Map of tags context, which gets merged with the current context (see
173194 `Sentry.Context.set_tags_context/1`) and with the `:tags` option in the global
174195 Sentry configuration. If fields collide, the ones in the map passed through
175196 this option have precedence over the ones in the context, which have precedence
176- over the ones in the configuration. Defaults to `%{}`.
177-
178- * `:request` - map of request context, which gets merged with the current context
197+ over the ones in the configuration.
198+ """
199+ ] ,
200+ request: [
201+ type: :map ,
202+ type_doc: "`t:Sentry.Context.request_context/0`" ,
203+ default: % { } ,
204+ doc: """
205+ Map of request context, which gets merged with the current context
179206 (see `Sentry.Context.set_request_context/1`). If fields collide, the ones
180207 in the map passed through this option have precedence over the ones in
181- the context. Defaults to `%{}`.
208+ the context.
209+ """
210+ ] ,
211+ breadcrumbs: [
212+ type: { :list , { :or , [ :keyword_list , :map ] } } ,
213+ type_doc: "list of `t:keyword/0` or `t:Sentry.Context.breadcrumb/0`" ,
214+ default: [ ] ,
215+ doc: """
216+ List of breadcrumbs. This list gets **prepended** to the list
217+ in the context (see `Sentry.Context.add_breadcrumb/1`).
218+ """
219+ ] ,
220+ level: [
221+ type: { :in , [ :fatal , :error , :warning , :info , :debug ] } ,
222+ type_doc: "`t:level/0`" ,
223+ default: :error ,
224+ doc: """
225+ The level of the event.
226+ """
227+ ] ,
228+ fingerprint: [
229+ type: { :list , :string } ,
230+ default: [ "{{ default }}" ] ,
231+ doc: """
232+ List of the fingerprint for grouping this event.
233+ """
234+ ] ,
235+ event_source: [
236+ type: :atom ,
237+ doc: """
238+ The source of the event. This fills in the `:source` field of the
239+ returned struct. This is not present by default.
240+ """
241+ ]
242+ ]
182243
183- * `:breadcrumbs` - list of breadcrumbs. This list gets **prepended** to the list
184- in the context (see `Sentry.Context.add_breadcrumb/1`). Defaults to `[]`.
244+ @ create_event_opts_schema NimbleOptions . new! ( create_event_opts_schema )
185245
186- * `:level` - error level (see `t:t/0`). Defaults to `:error`.
246+ @ doc """
247+ Creates an event struct out of collected context and options.
187248
188- * `:fingerprint` - list of the fingerprint for grouping this event (a list
189- of `t:String.t/0`). Defaults to `["{{ default }}"]`.
249+ > #### Merging Options with Context and Config {: .info}
250+ >
251+ > Some of the options documented below are **merged** with the Sentry context, or
252+ > with the Sentry context *and* the configuration. The option you pass here always
253+ > has higher precedence, followed by the context and finally by the configuration.
254+ >
255+ > See also `Sentry.Context` for information on the Sentry context and `Sentry` for
256+ > information on configuration.
190257
191- * `:event_source` - the source of the event. This fills in the `:source` field of the
192- returned struct. This is not present by default.
258+ ## Options
259+
260+ #{ NimbleOptions . docs ( @ create_event_opts_schema ) }
193261
194262 ## Examples
195263
@@ -220,6 +288,8 @@ defmodule Sentry.Event do
220288 | { :exception , Exception . t ( ) }
221289 | { :stacktrace , Exception . stacktrace ( ) }
222290 def create_event ( opts ) when is_list ( opts ) do
291+ opts = NimbleOptions . validate! ( opts , @ create_event_opts_schema )
292+
223293 timestamp =
224294 DateTime . utc_now ( )
225295 |> DateTime . truncate ( :microsecond )
@@ -234,20 +304,18 @@ defmodule Sentry.Event do
234304 request: request_context
235305 } = Sentry.Context . get_all ( )
236306
237- level = Keyword . get ( opts , :level , :error )
238- fingerprint = Keyword . get ( opts , :fingerprint , [ "{{ default }}" ] )
239-
240- extra = Map . merge ( extra_context , Keyword . get ( opts , :extra , % { } ) )
241- user = Map . merge ( user_context , Keyword . get ( opts , :user , % { } ) )
242- request = Map . merge ( request_context , Keyword . get ( opts , :request , % { } ) )
307+ extra = Map . merge ( extra_context , Keyword . fetch! ( opts , :extra ) )
308+ user = Map . merge ( user_context , Keyword . fetch! ( opts , :user ) )
309+ request = Map . merge ( request_context , Keyword . fetch! ( opts , :request ) )
243310
244311 tags =
245312 Config . tags ( )
246313 |> Map . merge ( tags_context )
247- |> Map . merge ( Keyword . get ( opts , :tags , % { } ) )
314+ |> Map . merge ( Keyword . fetch! ( opts , :tags ) )
248315
249316 breadcrumbs =
250- Keyword . get ( opts , :breadcrumbs , [ ] )
317+ opts
318+ |> Keyword . fetch! ( :breadcrumbs )
251319 |> Kernel . ++ ( breadcrumbs_context )
252320 |> Enum . take ( - 1 * Config . max_breadcrumbs ( ) )
253321 |> Enum . map ( & struct ( Interfaces.Breadcrumb , & 1 ) )
@@ -265,8 +333,8 @@ defmodule Sentry.Event do
265333 event_id: UUID . uuid4_hex ( ) ,
266334 exception: List . wrap ( coerce_exception ( exception , stacktrace , message ) ) ,
267335 extra: extra ,
268- fingerprint: fingerprint ,
269- level: level ,
336+ fingerprint: Keyword . fetch! ( opts , : fingerprint) ,
337+ level: Keyword . fetch! ( opts , : level) ,
270338 message: message ,
271339 modules: :persistent_term . get ( { :sentry , :loaded_applications } ) ,
272340 original_exception: exception ,
@@ -491,4 +559,13 @@ defmodule Sentry.Event do
491559 event . fingerprint
492560 ] )
493561 end
562+
563+ @ doc false
564+ def __validate_exception__ ( term , key ) do
565+ if is_exception ( term ) do
566+ { :ok , term }
567+ else
568+ { :error , "expected #{ inspect ( key ) } to be an exception, got: #{ inspect ( term ) } " }
569+ end
570+ end
494571end
0 commit comments