Skip to content

Commit a3af470

Browse files
committed
Fix NPE, prevent exceptions from crashing the walker at the frame.
1 parent dc2ffcc commit a3af470

1 file changed

Lines changed: 40 additions & 2 deletions

File tree

src/main/java/net/modfest/fireblanket/diagnostics/ForbiddenStackWalker.java

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -515,11 +515,29 @@ private static void consume(
515515
e
516516
);
517517
for (final var entry : witness) {
518-
logger.error("Encountered {}@{}", entry.getClass().getName(), System.identityHashCode(entry));
518+
logger.error("Encountered {}@{}", getMaybeClassName(entry), System.identityHashCode(entry));
519519
}
520520
}
521521
}
522522

523+
/**
524+
* Safely fetches the class name of the entry, returning {@code "** NULL **"} when null.
525+
*/
526+
private static String getMaybeClassName(final Object entry) {
527+
if (entry == null) {
528+
return "** NULL **";
529+
}
530+
final Class<?> clazz = entry.getClass();
531+
if (clazz == null) {
532+
return "** Non-compliant JVM: Object#getClass() returned null **";
533+
}
534+
final String name = clazz.getName();
535+
if (name == null) {
536+
return "** Non-compliant JVM: Class#getName() returned null **";
537+
}
538+
return name;
539+
}
540+
523541
/**
524542
* Trims the provided array of trailing primitive zeros.
525543
*
@@ -569,6 +587,9 @@ public static void print(
569587
/**
570588
* Prints all encountered objects to the provided {@link StringBuilder}.
571589
*
590+
* If it encounters an exception while printing an object,
591+
* it'll print the error, with the stack truncated to the stackwalker.
592+
*
572593
* @param builder The target string builder.
573594
* @param depth The tab depth. Used and incremented recursively to indent.
574595
* @param witness An IdentitySet. See {@link #newWitnessSet()}
@@ -583,8 +604,25 @@ private static void print(
583604
final Set<Object> witness,
584605
final Object... objects
585606
) {
607+
// Although the sinks are supposed to be non-null,
608+
// we cannot guarantee that everything sent to here is.
609+
if (objects == null) {
610+
builder.repeat('\t', depth).append("** NULL **\n");
611+
return;
612+
}
613+
586614
for (final var object : objects) {
587-
print(builder, depth, witness, object);
615+
try {
616+
print(builder, depth, witness, object);
617+
} catch (Throwable throwable) {
618+
final var tabCache = "\t".repeat(depth + 1);
619+
620+
builder.append('\n').append(tabCache).append("Terminated early: Object threw an error: ");
621+
622+
printIdentity(builder, object).append('\n');
623+
624+
printUntilFilter(builder.append(tabCache), tabCache, ForbiddenStackWalker.class, throwable);
625+
}
588626
}
589627
}
590628

0 commit comments

Comments
 (0)