Capturing Errors
Learn more about passing configuration options to a static Sentry#init method Sentry.
Copied
<dependency>
<groupId>io.sentry</groupId>
<artifactId>sentry</artifactId>
<version>8.47.0</version>
</dependency>
<dependency>
<groupId>io.sentry</groupId>
<artifactId>sentry</artifactId>
<version>8.47.0</version>
</dependency>
implementation 'io.sentry:sentry:8.47.0'
libraryDependencies += "io.sentry" % "sentry" % "8.47.0"
For other dependency managers see the central Maven repository.
When Sentry is used in manual way, configuration options must be passed to a static Sentry#init method:
Copied
import io.sentry.Sentry;
public class MyClass {
public static void main(String... args) {
Sentry.init(options -> {
// NOTE: Replace the test DSN below with YOUR OWN DSN to see the events from this app in
// your Sentry project/dashboard
options.setDsn("___PUBLIC_DSN___");
// All events get assigned to the release. See more at
// https://docs.sentry.io/workflow/releases/
options.setRelease("io.sentry.samples.console@4.2.0+1");
// Modifications to event before it goes out. Could replace the event altogether
options.setBeforeSend((event, hint) -> {
// Drop an event altogether:
if (event.getTag("SomeTag") != null) {
return null;
}
return event;
});
// Allows inspecting and modifying, returning a new or simply rejecting (returning null)
options.setBeforeBreadcrumb((breadcrumb, hint) -> {
// Don't add breadcrumbs with message containing:
if (breadcrumb.getMessage() != null
&& breadcrumb.getMessage().contains("bad breadcrumb")) {
return null;
}
return breadcrumb;
});
// Configure the background worker which sends events to sentry:
// Wait up to 5 seconds before shutdown while there are events to send.
options.setShutdownTimeout(5000);
// Enable SDK logging with Debug level
options.setDebug(true);
// To change the verbosity, use:
options.setDiagnosticLevel(
// By default it's DEBUG.
// A good option to have SDK debug log in prod is to use only level
// ERROR here.
SentryLevel.ERROR
);
// Exclude frames from some packages from being "inApp" so are hidden by default in Sentry
// UI:
options.addInAppExclude("org.jboss");
});
}
}
import io.sentry.Sentry;
public class MyClass {
public static void main(String... args) {
Sentry.init(options -> {
// NOTE: Replace the test DSN below with YOUR OWN DSN to see the events from this app in
// your Sentry project/dashboard
options.setDsn("___PUBLIC_DSN___");
// All events get assigned to the release. See more at
// https://docs.sentry.io/workflow/releases/
options.setRelease("io.sentry.samples.console@4.2.0+1");
// Modifications to event before it goes out. Could replace the event altogether
options.setBeforeSend((event, hint) -> {
// Drop an event altogether:
if (event.getTag("SomeTag") != null) {
return null;
}
return event;
});
// Allows inspecting and modifying, returning a new or simply rejecting (returning null)
options.setBeforeBreadcrumb((breadcrumb, hint) -> {
// Don't add breadcrumbs with message containing:
if (breadcrumb.getMessage() != null
&& breadcrumb.getMessage().contains("bad breadcrumb")) {
return null;
}
return breadcrumb;
});
// Configure the background worker which sends events to sentry:
// Wait up to 5 seconds before shutdown while there are events to send.
options.setShutdownTimeout(5000);
// Enable SDK logging with Debug level
options.setDebug(true);
// To change the verbosity, use:
options.setDiagnosticLevel(
// By default it's DEBUG.
// A good option to have SDK debug log in prod is to use only level
// ERROR here.
SentryLevel.ERROR
);
// Exclude frames from some packages from being "inApp" so are hidden by default in Sentry
// UI:
options.addInAppExclude("org.jboss");
});
}
}
import io.sentry.SentryOptions.BeforeBreadcrumbCallback
import io.sentry.SentryOptions.BeforeSendCallback
import io.sentry.Hint
fun main() {
Sentry.init { options ->
// NOTE: Replace the test DSN below with YOUR OWN DSN to see the events from this app in
// your Sentry project/dashboard
options.dsn = "___PUBLIC_DSN___"
// All events get assigned to the release. See more at
// https://docs.sentry.io/workflow/releases/
options.release = "io.sentry.samples.console@4.2.0+1"
// Modifications to event before it goes out. Could replace the event altogether
options.beforeSend = BeforeSendCallback { event: SentryEvent, hint: Hint ->
// Drop an event altogether:
if (event.getTag("SomeTag") != null) {
null
} else {
event
}
}
// Allows inspecting and modifying, returning a new or simply rejecting (returning null)
options.beforeBreadcrumb = BeforeBreadcrumbCallback { breadcrumb: Breadcrumb, hint: Hint ->
// Don't add breadcrumbs with message containing:
val message = breadcrumb.message
if (message?.contains("bad breadcrumb") == true) {
null
} else {
breadcrumb
}
}
// Configure the background worker which sends events to sentry:
// Wait up to 5 seconds before shutdown while there are events to send.
options.shutdownTimeout = 5000
// Enable SDK logging with Debug level
options.setDebug(true)
// To change the verbosity, use:
options.setDiagnosticLevel(
// By default it's DEBUG.
// A good option to have SDK debug log in prod is to use only level ERROR here.
SentryLevel.ERROR
)
// Exclude frames from some packages from being "inApp" so are hidden by default in Sentry
// UI:
options.addInAppExclude("org.jboss")
}
}
Find more configuration options in the Configuration section.
To report an event manually you need to initialize a Sentry class. It is recommended that you use the static API via the Sentry class. An example is shown below:
Copied
import io.sentry.Sentry;
import io.sentry.protocol.User;
public class MyClass {
public static void main(String... args) {
Sentry.init(options -> {
options.setDsn("___PUBLIC_DSN___");
});
MyClass myClass = new MyClass();
myClass.logWithStaticAPI();
}
/**
* An example method that throws an exception.
*/
void unsafeMethod() {
throw new UnsupportedOperationException("You shouldn't call this!");
}
/**
* Examples using the (recommended) static API.
*/
void logWithStaticAPI() {
// Note that all fields set on the scope are optional. Scope data is copied onto
// all future events in the current scope (until the scope is cleared).
// Record a breadcrumb in the current scope. By default the last 100 breadcrumbs are kept.
Sentry.addBreadcrumb("User made an action");
// Set the user in the current scope.
User user = new User();
user.setEmail("hello@sentry.io");
Sentry.setUser(user);
// Add extra data to future events in this scope.
Sentry.setExtra("extra", "thing");
// Add an additional tag to future events in this scope.
Sentry.setTag("tagName", "tagValue");
// This sends a simple event to Sentry using the statically stored instance
// that was created in the ``main`` method.
Sentry.captureMessage("This is a test");
try {
unsafeMethod();
} catch (Exception e) {
// This sends an exception event to Sentry using the statically stored instance
// that was created in the ``main`` method.
Sentry.captureException(e);
}
}
}
import io.sentry.Sentry;
import io.sentry.protocol.User;
public class MyClass {
public static void main(String... args) {
Sentry.init(options -> {
options.setDsn("___PUBLIC_DSN___");
});
MyClass myClass = new MyClass();
myClass.logWithStaticAPI();
}
/**
* An example method that throws an exception.
*/
void unsafeMethod() {
throw new UnsupportedOperationException("You shouldn't call this!");
}
/**
* Examples using the (recommended) static API.
*/
void logWithStaticAPI() {
// Note that all fields set on the scope are optional. Scope data is copied onto
// all future events in the current scope (until the scope is cleared).
// Record a breadcrumb in the current scope. By default the last 100 breadcrumbs are kept.
Sentry.addBreadcrumb("User made an action");
// Set the user in the current scope.
User user = new User();
user.setEmail("hello@sentry.io");
Sentry.setUser(user);
// Add extra data to future events in this scope.
Sentry.setExtra("extra", "thing");
// Add an additional tag to future events in this scope.
Sentry.setTag("tagName", "tagValue");
// This sends a simple event to Sentry using the statically stored instance
// that was created in the ``main`` method.
Sentry.captureMessage("This is a test");
try {
unsafeMethod();
} catch (Exception e) {
// This sends an exception event to Sentry using the statically stored instance
// that was created in the ``main`` method.
Sentry.captureException(e);
}
}
}
import io.sentry.Sentry
import io.sentry.SentryOptions
import io.sentry.protocol.User
class MyClass {
fun main(args: Array<String>) {
// NOTE: Replace the test DSN below with YOUR OWN DSN
Sentry.init { options ->
options.dsn = "___PUBLIC_DSN___"
}
val myClass = MyClass()
myClass.logWithStaticAPI()
}
/**
* An example method that throws an exception.
*/
fun unsafeMethod() {
throw UnsupportedOperationException("You shouldn't call this!")
}
/**
* Examples using the (recommended) static API.
*/
fun logWithStaticAPI() {
// Note that all fields set on the scope are optional. Scope data is copied onto
// all future events in the current scope (until the scope is cleared).
// Record a breadcrumb in the current scope. By default the last 100 breadcrumbs are kept.
Sentry.addBreadcrumb("User made an action")
// Set the user in the current scope.
val user = User().apply {
email = "hello@sentry.io"
}
Sentry.setUser(user)
// Add extra data to future events in this scope.
Sentry.setExtra("extra", "thing")
// Add an additional tag to future events in this scope.
Sentry.setTag("tagName", "tagValue")
// This sends a simple event to Sentry using the statically stored instance
// that was created in the ``main`` method.
Sentry.captureMessage("This is a test")
try {
unsafeMethod()
} catch (e: Exception) {
// This sends an exception event to Sentry using the statically stored instance
// that was created in the ``main`` method.
Sentry.captureException(e)
}
}
}
For more complex messages, you’ll need to build an SentryEvent object:
Copied
import io.sentry.Sentry;
import io.sentry.SentryEvent;
import io.sentry.SentryLevel;
import io.sentry.protocol.Message;
public class MyClass {
public static void main(String... args) {
// NOTE: Replace the test DSN below with YOUR OWN DSN
Sentry.init(options -> {
options.setDsn("___PUBLIC_DSN___");
});
}
void unsafeMethod() {
throw new UnsupportedOperationException("You shouldn't call this!");
}
void logSimpleMessage() {
// This sends an event to Sentry.
SentryEvent event = new SentryEvent();
Message message = new Message();
message.setMessage("This is a test");
event.setMessage(message);
event.setLevel(SentryLevel.INFO);
event.setLogger(MyClass.class.getName());
Sentry.captureEvent(event);
}
void logException() {
try {
unsafeMethod();
} catch (Exception e) {
// This sends an exception event to Sentry.
SentryEvent event = new SentryEvent();
Message message = new Message();
message.setMessage("Exception caught");
event.setMessage(message);
event.setLevel(SentryLevel.INFO);
event.setLogger(MyClass.class.getName());
event.setThrowable(e);
Sentry.captureEvent(event);
}
}
}
import io.sentry.Sentry;
import io.sentry.SentryEvent;
import io.sentry.SentryLevel;
import io.sentry.protocol.Message;
public class MyClass {
public static void main(String... args) {
// NOTE: Replace the test DSN below with YOUR OWN DSN
Sentry.init(options -> {
options.setDsn("___PUBLIC_DSN___");
});
}
void unsafeMethod() {
throw new UnsupportedOperationException("You shouldn't call this!");
}
void logSimpleMessage() {
// This sends an event to Sentry.
SentryEvent event = new SentryEvent();
Message message = new Message();
message.setMessage("This is a test");
event.setMessage(message);
event.setLevel(SentryLevel.INFO);
event.setLogger(MyClass.class.getName());
Sentry.captureEvent(event);
}
void logException() {
try {
unsafeMethod();
} catch (Exception e) {
// This sends an exception event to Sentry.
SentryEvent event = new SentryEvent();
Message message = new Message();
message.setMessage("Exception caught");
event.setMessage(message);
event.setLevel(SentryLevel.INFO);
event.setLogger(MyClass.class.getName());
event.setThrowable(e);
Sentry.captureEvent(event);
}
}
}
import io.sentry.Sentry
import io.sentry.SentryEvent
import io.sentry.SentryLevel
import io.sentry.protocol.Message
class MyClass {
fun main(args: Array<String>) {
// NOTE: Replace the test DSN below with YOUR OWN DSN
Sentry.init { options ->
options.dsn = "___PUBLIC_DSN___"
}
}
fun unsafeMethod() {
throw UnsupportedOperationException("You shouldn't call this!")
}
fun logSimpleMessage() {
// This sends an event to Sentry.
val event = SentryEvent().apply {
message = Message().apply {
message = "This is a test"
}
level = SentryLevel.INFO
logger = MyClass::class.java.name
}
Sentry.captureEvent(event)
}
fun logException() {
try {
unsafeMethod()
} catch (e: Exception) {
// This sends an exception event to Sentry.
val event = SentryEvent().apply {
message = Message().apply {
message = "Exception caught"
}
level = SentryLevel.INFO
logger = MyClass::class.java.name
throwable = e
}
Sentry.captureEvent(event)
}
}
}
You can also implement an EventProcessor that is able to automatically enhance outgoing events.
Copied
import io.sentry.EventProcessor;
import io.sentry.Sentry;
import io.sentry.SentryEvent;
import io.sentry.Hint
import io.sentry.protocol.Message;
public class MyClass {
public void myMethod() {
// Add an `EventProcessor` to the current scope. Note that
// this helper will process *all* future events in this scope.
Sentry.configureScope(scope -> {
scope.addEventProcessor(new EventProcessor() {
@Override
public SentryEvent process(SentryEvent event, Hint hint) {
Message message = new Message();
message.setMessage("Overwritten by myEventBuilderHelper!");
event.setMessage(message);
return event;
}
});
});
// Send an event to Sentry. During construction of the event the message
// body will be overwritten by the event processor.
Sentry.captureMessage("Hello, world!");
}
}
import io.sentry.EventProcessor;
import io.sentry.Sentry;
import io.sentry.SentryEvent;
import io.sentry.Hint
import io.sentry.protocol.Message;
public class MyClass {
public void myMethod() {
// Add an `EventProcessor` to the current scope. Note that
// this helper will process *all* future events in this scope.
Sentry.configureScope(scope -> {
scope.addEventProcessor(new EventProcessor() {
@Override
public SentryEvent process(SentryEvent event, Hint hint) {
Message message = new Message();
message.setMessage("Overwritten by myEventBuilderHelper!");
event.setMessage(message);
return event;
}
});
});
// Send an event to Sentry. During construction of the event the message
// body will be overwritten by the event processor.
Sentry.captureMessage("Hello, world!");
}
}
import io.sentry.Sentry
import io.sentry.Hint
import io.sentry.protocol.Message
class MyClass {
fun myMethod() {
// Add an `EventProcessor` to the current scope. Note that
// this helper will process *all* future events in this scope.
Sentry.configureScope { scope ->
scope.addEventProcessor(object: EventProcessor {
override fun process(event: SentryEvent, hint: Hint): SentryEvent? {
event.message = Message().apply {
message = "Overwritten by myEventBuilderHelper!"
}
return event
}
})
}
// Send an event to Sentry. During construction of the event the message
// body will be overwritten by the event processor.
Sentry.captureMessage("Hello, world!")
}
}
Was this helpful?
Help improve this content
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").