@@ -60,6 +60,24 @@ defmodule ErrorTracker do
6060 As we had seen before, you can use `ErrorTracker.report/3` to manually report an
6161 error. The third parameter of this function is optional and allows you to include
6262 extra context that will be tracked along with the error.
63+
64+ ## Breadcrumbs
65+
66+ Aside from contextual information, it is sometimes useful to know in which points
67+ of your code the code was executed in a given request / process.
68+
69+ Using breadcrumbs allows you to add that information to any error generated and
70+ stored on a given process / request. And if you are using `Ash` or `Splode`their
71+ exceptions' breadcrumbs will be automatically populated.
72+
73+ If you want to add a breadcrumb you can do so:
74+
75+ ```elixir
76+ ErrorTracker.add_breadcrumb("Executed my super secret code")
77+ ```
78+
79+ Breadcrumbs can be viewed in the dashboard while viewing the details of an
80+ occurrence.
6381 """
6482
6583 @ typedoc """
@@ -119,15 +137,14 @@ defmodule ErrorTracker do
119137 { :ok , stacktrace } = ErrorTracker.Stacktrace . new ( stacktrace )
120138 { :ok , error } = Error . new ( kind , reason , stacktrace )
121139 context = Map . merge ( get_context ( ) , given_context )
122-
123- context =
124- if bread_crumbs = bread_crumbs ( exception ) ,
125- do: Map . put ( context , "bread_crumbs" , bread_crumbs ) ,
126- else: context
140+ breadcrumbs = get_breadcrumbs ( ) ++ exception_breadcrumbs ( exception )
127141
128142 if enabled? ( ) && ! ignored? ( error , context ) do
129143 sanitized_context = sanitize_context ( context )
130- { _error , occurrence } = upsert_error! ( error , stacktrace , sanitized_context , reason )
144+
145+ { _error , occurrence } =
146+ upsert_error! ( error , stacktrace , sanitized_context , breadcrumbs , reason )
147+
131148 occurrence
132149 else
133150 :noop
@@ -205,6 +222,40 @@ defmodule ErrorTracker do
205222 Process . get ( :error_tracker_context , % { } )
206223 end
207224
225+ @ doc """
226+ Adds a breadcrumb to the current process.
227+
228+ The new breadcrumb will be added as the most recent entry of the breadcrumbs
229+ list.
230+
231+ ## Breadcrumbs limit
232+
233+ Breadcrumbs are a powerful tool that allows to add an infinite number of
234+ entries. However, it is not recommended to store errors with an excessive
235+ amount of breadcrumbs.
236+
237+ As they are stored as an array of strings under the hood, storing many
238+ entries per error can lead to some delays and using extra disk space on the
239+ database.
240+ """
241+ @ spec add_breadcrumb ( String . t ( ) ) :: list ( String . t ( ) )
242+ def add_breadcrumb ( breadcrumb ) when is_binary ( breadcrumb ) do
243+ current_breadcrumbs = Process . get ( :error_tracker_breadcrumbs , [ ] )
244+ new_breadcrumbs = current_breadcrumbs ++ [ breadcrumb ]
245+
246+ Process . put ( :error_tracker_breadcrumbs , new_breadcrumbs )
247+
248+ new_breadcrumbs
249+ end
250+
251+ @ doc """
252+ Obtain the breadcrumbs of the current process.
253+ """
254+ @ spec get_breadcrumbs ( ) :: list ( String . t ( ) )
255+ def get_breadcrumbs do
256+ Process . get ( :error_tracker_breadcrumbs , [ ] )
257+ end
258+
208259 defp enabled? do
209260 ! ! Application . get_env ( :error_tracker , :enabled , true )
210261 end
@@ -237,15 +288,15 @@ defmodule ErrorTracker do
237288 end
238289 end
239290
240- defp bread_crumbs ( exception ) do
291+ defp exception_breadcrumbs ( exception ) do
241292 case exception do
242- { _kind , exception } -> bread_crumbs ( exception )
243- % { bread_crumbs: bread_crumbs } -> bread_crumbs
244- _other -> nil
293+ { _kind , exception } -> exception_breadcrumbs ( exception )
294+ % { bread_crumbs: breadcrumbs } -> breadcrumbs
295+ _other -> [ ]
245296 end
246297 end
247298
248- defp upsert_error! ( error , stacktrace , context , reason ) do
299+ defp upsert_error! ( error , stacktrace , context , breadcrumbs , reason ) do
249300 existing_status =
250301 Repo . one ( from e in Error , where: [ fingerprint: ^ error . fingerprint ] , select: e . status )
251302
@@ -271,6 +322,7 @@ defmodule ErrorTracker do
271322 |> Occurrence . changeset ( % {
272323 stacktrace: stacktrace ,
273324 context: context ,
325+ breadcrumbs: breadcrumbs ,
274326 reason: reason
275327 } )
276328 |> Repo . insert! ( )
0 commit comments