Send custom errors
After you set it up, Faro Web SDK automatically handles and reports all unhandled exceptions and rejected promises.
Unhandled errors are errors that are not identified in a try/catch
block and are picked up by the global error handler.
Consider the following example:
In the following example, the someOperation
function generates an error that can potentially break your app because it is not handled properly.
Similarly, rejected promises are asynchronous functions (Promises) that fail and are not handled by a .catch(error => {})
or a try/catch
block in an async/await
context.
function someOperation() {
throw new Error('I am supposed to fail');
}
function main() {
someOperation();
}
main();
In this case, if fetch
fails for any reason, the error propagates to the global promise rejection handler.
async function getUsers() {
const users = await fetch('/api/users');
return users;
}
async function main() {
const userList = await getUsers();
// render the user list
}
main();
Faro Web SDK automatically hooks into both of these handlers and reports the error back to the collector endpoint.
These events are ingested by a Loki instance as logs with a specific label kind=error
.
For more information about Loki labels, refer to Labels.
When to report errors manually
Faro reports only unhandled errors, which means if you have already implemented an error handling mechanism (for example, ErrorBoundary
for React Apps), you should manually add Faro Web SDK to the error handling pipeline.
Before you begin
- Ensure you have registered your app in the Frontend Observability plugin
- Set up the Faro Web SDK from the quickstart or instrumentation documentation.
Steps
After it is initialized, Faro is an instance that can be accessed either by importing it from the @grafana/faro-web-sdk
or referencing it from the window
global object.
// Import the global faro instance
import { faro } from '@grafana/faro-web-sdk';
The faro.api
object is a wrapper of the Faro API and provides a pushError
method with which you can send any error.
You can also provide the stack frames, or manually set the type of event for better filtering.
// Send custom errors with faro
// 1. Simple error generated at some point in your application
// 2. Namespaced error
// Supposed this error is generated somewhere in your app
const error = new Error('I am supposed to fail');
// ...
// And at some point you want to pipe it to Faro
faro.api.pushError(error);
// Different type
const error = new Error('I am an error generated by network requests');
// ...
faro.api.pushError(error, {
type: 'network',
});
// with additional contextual attributes
faro.api.pushError(error, {
type: 'network',
context: {
message: 'React error boundary',
componentStackTrace: {...}
},
});
API
The exceptions API allows you to pass the following parameters and options:
pushError: (value: Error, options?: PushErrorOptions)
Parameters
Name | Description |
---|---|
value | A JavaScript error |
options | Configure the behavior of the push API or inject additional data to change the signal data. |
Push error options
Name | Description |
---|---|
stackFrames | A list of stack frames |
type | The type of error |
context | Includes additional error context |
skipDedupe | Pushes the signal even if it is identical to the previous one |
spanContext | Provides a custom spanContext to the signal |
timestampOverwriteMs | The timestamp represents the exact moment when the respective API was called. In most cases, this precision is sufficient. The timestampOverwriteMs option allows you to pass an adjustment timestamp which can be used instead. |