Crash reports now include the stacktrace of .report()

This commit is contained in:
OLEGSHA 2021-01-10 23:00:49 +03:00
parent c1b1d930ce
commit 9d305890d1
4 changed files with 30 additions and 43 deletions

View File

@ -17,7 +17,7 @@ note that JDK is not the same as a JRE (Java Runtime Environment), the software
you may be able to run Progressia but not compile it. you may be able to run Progressia but not compile it.
To check whether you have the correct JDK installed please run To check whether you have the correct JDK installed please run
`javac --version`. `javac -version`.
If this command fails or outputs version 1.7 or lower, then you need to (re-)install JDK. (javac is the Java If this command fails or outputs version 1.7 or lower, then you need to (re-)install JDK. (javac is the Java
Compiler.) Compiler.)

View File

@ -39,7 +39,6 @@ public class ProgressiaLauncher {
CrashReports.registerProvider(new OpenALContextProvider()); CrashReports.registerProvider(new OpenALContextProvider());
CrashReports.registerProvider(new ArgsContextProvider()); CrashReports.registerProvider(new ArgsContextProvider());
CrashReports.registerProvider(new LanguageContextProvider()); CrashReports.registerProvider(new LanguageContextProvider());
CrashReports.registerProvider(new StackTraceProvider());
// Analyzers // Analyzers
CrashReports.registerAnalyzer(new OutOfMemoryAnalyzer()); CrashReports.registerAnalyzer(new OutOfMemoryAnalyzer());

View File

@ -2,14 +2,11 @@ package ru.windcorp.progressia.common.util.crash;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.util.StringBuilderWriter;
import ru.windcorp.jputil.chars.StringUtil; import ru.windcorp.jputil.chars.StringUtil;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@ -88,6 +85,8 @@ public class CrashReports {
* @return {@code null}, although this method never returns normally. Provided for convenience. * @return {@code null}, although this method never returns normally. Provided for convenience.
*/ */
public static RuntimeException crash(Throwable throwable, String messageFormat, Object... args) { public static RuntimeException crash(Throwable throwable, String messageFormat, Object... args) {
final StackTraceElement[] reportStackTrace;
if (throwable instanceof ReportedException) { if (throwable instanceof ReportedException) {
ReportedException reportedException = (ReportedException) throwable; ReportedException reportedException = (ReportedException) throwable;
@ -95,6 +94,10 @@ public class CrashReports {
throwable = reportedException.getCause(); throwable = reportedException.getCause();
messageFormat = reportedException.getMessageFormat(); messageFormat = reportedException.getMessageFormat();
args = reportedException.getArgs(); args = reportedException.getArgs();
reportStackTrace = reportedException.getStackTrace();
} else {
reportStackTrace = getCurrentStackTrace();
} }
StringBuilder output = new StringBuilder(); StringBuilder output = new StringBuilder();
@ -127,7 +130,9 @@ public class CrashReports {
appendMessageFormat(output, messageFormat, args); appendMessageFormat(output, messageFormat, args);
appendStackTrace(output, throwable); appendStackTrace(output, reportStackTrace, "Reported at:");
output.append('\n');
appendThrowable(output, throwable);
export(output.toString()); export(output.toString());
@ -135,7 +140,14 @@ public class CrashReports {
return null; return null;
} }
private static void appendContextProviders(StringBuilder output) { private static StackTraceElement[] getCurrentStackTrace() {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
final int trim = 3;
return Arrays.copyOfRange(stackTrace, trim, stackTrace.length);
}
private static void appendContextProviders(StringBuilder output) {
// Do a local copy to avoid deadlocks -OLEGSHA // Do a local copy to avoid deadlocks -OLEGSHA
ContextProvider[] localProvidersCopy = PROVIDERS.toArray(new ContextProvider[PROVIDERS.size()]); ContextProvider[] localProvidersCopy = PROVIDERS.toArray(new ContextProvider[PROVIDERS.size()]);
@ -225,22 +237,22 @@ public class CrashReports {
addSeparator(output); addSeparator(output);
} }
private static void appendStackTrace(StringBuilder output, Throwable throwable) { private static void appendThrowable(StringBuilder output, Throwable throwable) {
output.append("Stacktrace: \n");
if (throwable == null) { if (throwable == null) {
output.append("no Throwable provided").append("\n"); output.append("No Throwable provided").append("\n");
return; return;
} }
// Formatting to a human-readable string output.append("Reported Throwable:\n");
Writer sink = new StringBuilderWriter(output); appendStackTrace(output, throwable.getStackTrace(), throwable.toString());
try { }
throwable.printStackTrace(new PrintWriter(sink));
} catch (Exception e) { private static void appendStackTrace(StringBuilder output, StackTraceElement[] stackTrace, String header) {
// PLAK output.append(header).append('\n');
for (StackTraceElement element : stackTrace) {
output.append('\t').append(element).append('\n');
} }
output.append("\n");
} }
private static void export(String report) { private static void export(String report) {

View File

@ -1,24 +0,0 @@
package ru.windcorp.progressia.common.util.crash.providers;
import ru.windcorp.progressia.common.util.crash.ContextProvider;
import java.util.Map;
public class StackTraceProvider implements ContextProvider {
@Override
public void provideContext(Map<String, String> output) {
StackTraceElement[] stackTraceBuffer = Thread.currentThread().getStackTrace();
StringBuilder sb = new StringBuilder();
sb.append("\n");
for (int i = 4; i < stackTraceBuffer.length; i++) {
sb.append('\t').append(stackTraceBuffer[i].toString()).append("\n");
}
output.put("Reported from " + Thread.currentThread().getName(), sb.toString());
}
@Override
public String getName() {
return "Stack Trace Context Provider";
}
}