Skip to content

Commit 8a070f8

Browse files
adinauerclaude
andcommitted
fix(jul): Handle null messages with resource bundles
Skip resource-bundle lookup and message formatting when a JUL record has no message. Preserve event and breadcrumb capture instead of aborting with a null-pointer exception. Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 855d289 commit 8a070f8

2 files changed

Lines changed: 45 additions & 5 deletions

File tree

‎sentry-jul/src/main/java/io/sentry/jul/SentryHandler.java‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.Date;
2929
import java.util.List;
3030
import java.util.Map;
31+
import java.util.ResourceBundle;
3132
import java.util.logging.ErrorManager;
3233
import java.util.logging.Filter;
3334
import java.util.logging.Handler;
@@ -295,13 +296,16 @@ SentryEvent createEvent(final @NotNull LogRecord record) {
295296
final Message sentryMessage = new Message();
296297
sentryMessage.setParams(toParams(record.getParameters()));
297298

298-
String message = record.getMessage();
299-
if (record.getResourceBundle() != null
300-
&& record.getResourceBundle().containsKey(record.getMessage())) {
301-
message = record.getResourceBundle().getString(record.getMessage());
299+
final @Nullable String messageTemplate = record.getMessage();
300+
final @Nullable ResourceBundle resourceBundle = record.getResourceBundle();
301+
@Nullable String message = messageTemplate;
302+
if (messageTemplate != null
303+
&& resourceBundle != null
304+
&& resourceBundle.containsKey(messageTemplate)) {
305+
message = resourceBundle.getString(messageTemplate);
302306
}
303307
sentryMessage.setMessage(message);
304-
if (record.getParameters() != null) {
308+
if (message != null && record.getParameters() != null) {
305309
try {
306310
sentryMessage.setFormatted(formatMessage(message, record.getParameters()));
307311
} catch (RuntimeException e) {

‎sentry-jul/src/test/kotlin/io/sentry/jul/SentryHandlerTest.kt‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ import io.sentry.transport.ITransport
1616
import java.time.Instant
1717
import java.time.LocalDateTime
1818
import java.time.ZoneId
19+
import java.util.ListResourceBundle
1920
import java.util.logging.Level
21+
import java.util.logging.LogRecord
2022
import java.util.logging.Logger
2123
import kotlin.test.AfterTest
2224
import kotlin.test.BeforeTest
@@ -510,6 +512,40 @@ class SentryHandlerTest {
510512
verify(fixture.transport, never()).send(checkLogs {})
511513
}
512514

515+
@Test
516+
fun `captures null message as event and breadcrumb when resource bundle is set`() {
517+
fixture =
518+
Fixture(
519+
minimumBreadcrumbLevel = Level.INFO,
520+
minimumEventLevel = Level.SEVERE,
521+
enableLogs = true,
522+
)
523+
val resourceBundle =
524+
object : ListResourceBundle() {
525+
override fun getContents(): Array<Array<Any>> =
526+
arrayOf(arrayOf<Any>("message", "localized message"))
527+
}
528+
529+
fixture.handler.publish(
530+
LogRecord(Level.INFO, null).apply { this.resourceBundle = resourceBundle }
531+
)
532+
fixture.handler.publish(
533+
LogRecord(Level.SEVERE, null).apply { this.resourceBundle = resourceBundle }
534+
)
535+
Sentry.flush(10)
536+
537+
verify(fixture.transport)
538+
.send(
539+
checkEvent { event ->
540+
assertNull(event.message?.message)
541+
assertEquals(1, event.breadcrumbs?.size)
542+
assertNull(event.breadcrumbs?.single()?.message)
543+
},
544+
anyOrNull(),
545+
)
546+
verify(fixture.transport, never()).send(checkLogs {})
547+
}
548+
513549
@Test
514550
fun `converts finest log level to Sentry log level`() {
515551
fixture = Fixture(minimumLevel = Level.FINEST)

0 commit comments

Comments
 (0)