@@ -20,6 +20,9 @@ defmodule Sentry.Context do
2020 posts = Blog.list_posts()
2121 render(conn, "index.html", posts: posts)
2222 end
23+
24+ It should be noted that the `set_*_context/1` functions merge with the
25+ existing context rather than entirely overwriting it.
2326 """
2427 @ process_dictionary_key :sentry_context
2528 @ user_key :user
@@ -28,6 +31,29 @@ defmodule Sentry.Context do
2831 @ request_key :request
2932 @ breadcrumbs_key :breadcrumbs
3033
34+ @ doc """
35+ Retrieves all currently set context on the current process.
36+
37+ ## Example
38+
39+ iex> Sentry.Context.set_user_context(%{id: 123})
40+ iex> Sentry.Context.set_tags_context(%{message_id: 456})
41+ iex> Sentry.Context.get_all()
42+ %{
43+ user: %{id: 123},
44+ tags: %{message_id: 456},
45+ extra: %{},
46+ request: %{},
47+ breadcrumbs: []
48+ }
49+ """
50+ @ spec get_all ( ) :: % {
51+ user: map ( ) ,
52+ tags: map ( ) ,
53+ extra: map ( ) ,
54+ request: map ( ) ,
55+ breadcrumbs: list ( )
56+ }
3157 def get_all do
3258 context = get_context ( )
3359
@@ -40,26 +66,129 @@ defmodule Sentry.Context do
4066 }
4167 end
4268
69+ @ doc """
70+ Merges new fields into the `:extra` context, specific to the current process.
71+
72+ This is used to set fields which should display when looking at a specific
73+ instance of an error.
74+
75+ ## Example
76+
77+ iex> Sentry.Context.set_extra_context(%{id: 123})
78+ nil
79+ iex> Sentry.Context.set_extra_context(%{detail: "bad_error"})
80+ %{extra: %{id: 123}}
81+ iex> Sentry.Context.set_extra_context(%{message: "Oh no"})
82+ %{extra: %{detail: "bad_error", id: 123}}
83+ iex> Sentry.Context.get_all()
84+ %{
85+ user: %{},
86+ tags: %{},
87+ extra: %{detail: "bad_error", id: 123, message: "Oh no"},
88+ request: %{},
89+ breadcrumbs: []
90+ }
91+ """
92+ @ spec set_extra_context ( map ( ) ) :: nil | map ( )
4393 def set_extra_context ( map ) when is_map ( map ) do
4494 get_context ( )
4595 |> set_context ( @ extra_key , map )
4696 end
4797
98+ @ doc """
99+ Merges new fields into the `:user` context, specific to the current process.
100+
101+ This is used to set certain fields which identify the actor who experienced a
102+ specific instance of an error.
103+
104+ ## Example
105+
106+ iex> Sentry.Context.set_user_context(%{id: 123})
107+ nil
108+ iex> Sentry.Context.set_user_context(%{username: "george"})
109+ %{user: %{id: 123}}
110+ iex> Sentry.Context.get_all()
111+ %{
112+ user: %{id: 123, username: "george"},
113+ tags: %{},
114+ extra: %{},
115+ request: %{},
116+ breadcrumbs: []
117+ }
118+ """
119+ @ spec set_user_context ( map ( ) ) :: nil | map ( )
48120 def set_user_context ( map ) when is_map ( map ) do
49121 get_context ( )
50122 |> set_context ( @ user_key , map )
51123 end
52124
125+ @ doc """
126+ Merges new fields into the `:tags` context, specific to the current process.
127+
128+ This is used to set fields which should display when looking at a specific
129+ instance of an error. These fields can also be used to search and filter on.
130+
131+ ## Example
132+
133+ iex> Sentry.Context.set_tags_context(%{id: 123})
134+ nil
135+ iex> Sentry.Context.set_tags_context(%{other_id: 456})
136+ %{tags: %{id: 123}}
137+ iex> Sentry.Context.get_all()
138+ %{
139+ breadcrumbs: [],
140+ extra: %{},
141+ request: %{},
142+ tags: %{id: 123, other_id: 456},
143+ user: %{}
144+ }
145+ """
146+ @ spec set_tags_context ( map ( ) ) :: nil | map ( )
53147 def set_tags_context ( map ) when is_map ( map ) do
54148 get_context ( )
55149 |> set_context ( @ tags_key , map )
56150 end
57151
152+ @ doc """
153+ Merges new fields into the `:request` context, specific to the current
154+ process.
155+
156+ This is used to set metadata that identifies the request associated with a
157+ specific instance of an error.
158+
159+ ## Example
160+
161+ iex(1)> Sentry.Context.set_http_context(%{id: 123})
162+ nil
163+ iex(2)> Sentry.Context.set_http_context(%{url: "www.example.com"})
164+ %{request: %{id: 123}}
165+ iex(3)> Sentry.Context.get_all()
166+ %{
167+ breadcrumbs: [],
168+ extra: %{},
169+ request: %{id: 123, url: "www.example.com"},
170+ tags: %{},
171+ user: %{}
172+ }
173+ """
174+ @ spec set_http_context ( map ( ) ) :: nil | map ( )
58175 def set_http_context ( map ) when is_map ( map ) do
59176 get_context ( )
60177 |> set_context ( @ request_key , map )
61178 end
62179
180+ @ doc """
181+ Clears all existing context for the current process.
182+
183+ ## Example
184+
185+ iex> Sentry.Context.set_tags_context(%{id: 123})
186+ nil
187+ iex> Sentry.Context.clear_all()
188+ %{tags: %{id: 123}}
189+ iex> Sentry.Context.get_all()
190+ %{breadcrumbs: [], extra: %{}, request: %{}, tags: %{}, user: %{}}
191+ """
63192 def clear_all do
64193 Process . delete ( @ process_dictionary_key )
65194 end
@@ -68,8 +197,52 @@ defmodule Sentry.Context do
68197 Process . get ( @ process_dictionary_key ) || % { }
69198 end
70199
200+ @ doc """
201+ Adds a new breadcrumb to the `:breadcrumb` context, specific to the current
202+ process.
203+
204+ Breadcrumbs are used to record a series of events that led to a specific
205+ instance of an error. Breadcrumbs can contain arbitrary key data to assist in
206+ understanding what happened before an error occurred.
207+
208+ ## Example
209+
210+ iex> Sentry.Context.add_breadcrumb(message: "first_event")
211+ nil
212+ iex> Sentry.Context.add_breadcrumb(%{message: "second_event", type: "auth"})
213+ %{breadcrumbs: [%{:message => "first_event", "timestamp" => 1562007480}]}
214+ iex> Sentry.Context.add_breadcrumb(%{message: "response"})
215+ %{
216+ breadcrumbs: [
217+ %{:message => "second_event", :type => "auth", "timestamp" => 1562007505},
218+ %{:message => "first_event", "timestamp" => 1562007480}
219+ ]
220+ }
221+ iex> Sentry.Context.get_all()
222+ %{
223+ breadcrumbs: [
224+ %{:message => "first_event", "timestamp" => 1562007480},
225+ %{:message => "second_event", :type => "auth", "timestamp" => 1562007505},
226+ %{:message => "response", "timestamp" => 1562007517}
227+ ],
228+ extra: %{},
229+ request: %{},
230+ tags: %{},
231+ user: %{}
232+ }
233+ """
234+ @ spec add_breadcrumb ( keyword ( ) | map ( ) ) :: nil | map ( )
71235 def add_breadcrumb ( list ) when is_list ( list ) do
72- add_breadcrumb ( Enum . into ( list , % { } ) )
236+ if Keyword . keyword? ( list ) do
237+ list
238+ |> Enum . into ( % { } )
239+ |> add_breadcrumb
240+ else
241+ raise ArgumentError , """
242+ Sentry.Context.add_breadcrumb/1 only accepts keyword lists or maps.
243+ Received a non-keyword list.
244+ """
245+ end
73246 end
74247
75248 def add_breadcrumb ( map ) when is_map ( map ) do
@@ -92,6 +265,16 @@ defmodule Sentry.Context do
92265 Process . put ( @ process_dictionary_key , new_context )
93266 end
94267
268+ @ doc """
269+ Returns the keys used to store context in the current Process's process
270+ dictionary.
271+
272+ ## Example
273+
274+ iex> Sentry.Context.context_keys()
275+ [:breadcrumbs, :tags, :user, :extra]
276+ """
277+ @ spec context_keys ( ) :: list ( atom ( ) )
95278 def context_keys do
96279 [ @ breadcrumbs_key , @ tags_key , @ user_key , @ extra_key ]
97280 end
0 commit comments