CrashReport.java

net.minecraft.CrashReport

信息

  • 全限定名:net.minecraft.CrashReport
  • 类型:public class
  • 包:net.minecraft
  • 源码路径:src/main/java/net/minecraft/CrashReport.java
  • 起始行号:L23
  • 职责:

    TODO

字段/常量

  • LOGGER

    • 类型: Logger
    • 修饰符: private static final
    • 源码定位: L24
    • 说明:

      TODO

  • DATE_TIME_FORMATTER

    • 类型: DateTimeFormatter
    • 修饰符: private static final
    • 源码定位: L25
    • 说明:

      TODO

  • title

    • 类型: String
    • 修饰符: private final
    • 源码定位: L26
    • 说明:

      TODO

  • exception

    • 类型: Throwable
    • 修饰符: private final
    • 源码定位: L27
    • 说明:

      TODO

  • details

    • 类型: List<CrashReportCategory>
    • 修饰符: private final
    • 源码定位: L28
    • 说明:

      TODO

  • saveFile

    • 类型: Path
    • 修饰符: private
    • 源码定位: L29
    • 说明:

      TODO

  • trackingStackTrace

    • 类型: boolean
    • 修饰符: private
    • 源码定位: L30
    • 说明:

      TODO

  • uncategorizedStackTrace

    • 类型: StackTraceElement[]
    • 修饰符: private
    • 源码定位: L31
    • 说明:

      TODO

  • systemReport

    • 类型: SystemReport
    • 修饰符: private final
    • 源码定位: L32
    • 说明:

      TODO

内部类/嵌套类型

构造器

public CrashReport(String title, Throwable t) @ L34

  • 构造器名:CrashReport
  • 源码定位:L34
  • 修饰符:public

参数:

  • title: String
  • t: Throwable

说明:

TODO

方法

下面的方法块按源码顺序生成。

public String getTitle() @ L39

  • 方法名:getTitle
  • 源码定位:L39
  • 返回类型:String
  • 修饰符:public

参数:

说明:

TODO

public Throwable getException() @ L43

  • 方法名:getException
  • 源码定位:L43
  • 返回类型:Throwable
  • 修饰符:public

参数:

说明:

TODO

public String getDetails() @ L47

  • 方法名:getDetails
  • 源码定位:L47
  • 返回类型:String
  • 修饰符:public

参数:

说明:

TODO

public void getDetails(StringBuilder builder) @ L53

  • 方法名:getDetails
  • 源码定位:L53
  • 返回类型:void
  • 修饰符:public

参数:

  • builder: StringBuilder

说明:

TODO

public String getExceptionMessage() @ L79

  • 方法名:getExceptionMessage
  • 源码定位:L79
  • 返回类型:String
  • 修饰符:public

参数:

说明:

TODO

public String getFriendlyReport(ReportType reportType, List<String> extraComments) @ L109

  • 方法名:getFriendlyReport
  • 源码定位:L109
  • 返回类型:String
  • 修饰符:public

参数:

  • reportType: ReportType
  • extraComments: List

说明:

TODO

public String getFriendlyReport(ReportType reportType) @ L130

  • 方法名:getFriendlyReport
  • 源码定位:L130
  • 返回类型:String
  • 修饰符:public

参数:

  • reportType: ReportType

说明:

TODO

public Path getSaveFile() @ L134

  • 方法名:getSaveFile
  • 源码定位:L134
  • 返回类型:Path
  • 修饰符:public

参数:

说明:

TODO

public boolean saveToFile(Path saveFile, ReportType reportType, List<String> extraComments) @ L138

  • 方法名:saveToFile
  • 源码定位:L138
  • 返回类型:boolean
  • 修饰符:public

参数:

  • saveFile: Path
  • reportType: ReportType
  • extraComments: List

说明:

TODO

public boolean saveToFile(Path file, ReportType reportType) @ L160

  • 方法名:saveToFile
  • 源码定位:L160
  • 返回类型:boolean
  • 修饰符:public

参数:

  • file: Path
  • reportType: ReportType

说明:

TODO

public SystemReport getSystemReport() @ L164

  • 方法名:getSystemReport
  • 源码定位:L164
  • 返回类型:SystemReport
  • 修饰符:public

参数:

说明:

TODO

public CrashReportCategory addCategory(String name) @ L168

  • 方法名:addCategory
  • 源码定位:L168
  • 返回类型:CrashReportCategory
  • 修饰符:public

参数:

  • name: String

说明:

TODO

public CrashReportCategory addCategory(String name, int nestedOffset) @ L172

  • 方法名:addCategory
  • 源码定位:L172
  • 返回类型:CrashReportCategory
  • 修饰符:public

参数:

  • name: String
  • nestedOffset: int

说明:

TODO

public static CrashReport forThrowable(Throwable t, String title) @ L204

  • 方法名:forThrowable
  • 源码定位:L204
  • 返回类型:CrashReport
  • 修饰符:public static

参数:

  • t: Throwable
  • title: String

说明:

TODO

public static void preload() @ L219

  • 方法名:preload
  • 源码定位:L219
  • 返回类型:void
  • 修饰符:public static

参数:

说明:

TODO

代码

public class CrashReport {
    private static final Logger LOGGER = LogUtils.getLogger();
    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.ROOT);
    private final String title;
    private final Throwable exception;
    private final List<CrashReportCategory> details = Lists.newArrayList();
    private @Nullable Path saveFile;
    private boolean trackingStackTrace = true;
    private StackTraceElement[] uncategorizedStackTrace = new StackTraceElement[0];
    private final SystemReport systemReport = new SystemReport();
 
    public CrashReport(String title, Throwable t) {
        this.title = title;
        this.exception = t;
    }
 
    public String getTitle() {
        return this.title;
    }
 
    public Throwable getException() {
        return this.exception;
    }
 
    public String getDetails() {
        StringBuilder builder = new StringBuilder();
        this.getDetails(builder);
        return builder.toString();
    }
 
    public void getDetails(StringBuilder builder) {
        if ((this.uncategorizedStackTrace == null || this.uncategorizedStackTrace.length <= 0) && !this.details.isEmpty()) {
            this.uncategorizedStackTrace = ArrayUtils.subarray(this.details.get(0).getStacktrace(), 0, 1);
        }
 
        if (this.uncategorizedStackTrace != null && this.uncategorizedStackTrace.length > 0) {
            builder.append("-- Head --\n");
            builder.append("Thread: ").append(Thread.currentThread().getName()).append("\n");
            builder.append("Stacktrace:\n");
 
            for (StackTraceElement element : this.uncategorizedStackTrace) {
                builder.append("\t").append("at ").append(element);
                builder.append("\n");
            }
 
            builder.append("\n");
        }
 
        for (CrashReportCategory entry : this.details) {
            entry.getDetails(builder);
            builder.append("\n\n");
        }
 
        this.systemReport.appendToCrashReportString(builder);
    }
 
    public String getExceptionMessage() {
        StringWriter writer = null;
        PrintWriter printWriter = null;
        Throwable exception = this.exception;
        if (exception.getMessage() == null) {
            if (exception instanceof NullPointerException) {
                exception = new NullPointerException(this.title);
            } else if (exception instanceof StackOverflowError) {
                exception = new StackOverflowError(this.title);
            } else if (exception instanceof OutOfMemoryError) {
                exception = new OutOfMemoryError(this.title);
            }
 
            exception.setStackTrace(this.exception.getStackTrace());
        }
 
        String var4;
        try {
            writer = new StringWriter();
            printWriter = new PrintWriter(writer);
            exception.printStackTrace(printWriter);
            var4 = writer.toString();
        } finally {
            IOUtils.closeQuietly((Writer)writer);
            IOUtils.closeQuietly((Writer)printWriter);
        }
 
        return var4;
    }
 
    public String getFriendlyReport(ReportType reportType, List<String> extraComments) {
        StringBuilder builder = new StringBuilder();
        reportType.appendHeader(builder, extraComments);
        builder.append("Time: ");
        builder.append(DATE_TIME_FORMATTER.format(ZonedDateTime.now()));
        builder.append("\n");
        builder.append("Description: ");
        builder.append(this.title);
        builder.append("\n\n");
        builder.append(this.getExceptionMessage());
        builder.append("\n\nA detailed walkthrough of the error, its code path and all known details is as follows:\n");
 
        for (int i = 0; i < 87; i++) {
            builder.append("-");
        }
 
        builder.append("\n\n");
        this.getDetails(builder);
        return builder.toString();
    }
 
    public String getFriendlyReport(ReportType reportType) {
        return this.getFriendlyReport(reportType, List.of());
    }
 
    public @Nullable Path getSaveFile() {
        return this.saveFile;
    }
 
    public boolean saveToFile(Path saveFile, ReportType reportType, List<String> extraComments) {
        if (this.saveFile != null) {
            return false;
        } else {
            try {
                if (saveFile.getParent() != null) {
                    FileUtil.createDirectoriesSafe(saveFile.getParent());
                }
 
                try (Writer writer = Files.newBufferedWriter(saveFile, StandardCharsets.UTF_8)) {
                    writer.write(this.getFriendlyReport(reportType, extraComments));
                }
 
                this.saveFile = saveFile;
                return true;
            } catch (Throwable var9) {
                LOGGER.error("Could not save crash report to {}", saveFile, var9);
                return false;
            }
        }
    }
 
    public boolean saveToFile(Path file, ReportType reportType) {
        return this.saveToFile(file, reportType, List.of());
    }
 
    public SystemReport getSystemReport() {
        return this.systemReport;
    }
 
    public CrashReportCategory addCategory(String name) {
        return this.addCategory(name, 1);
    }
 
    public CrashReportCategory addCategory(String name, int nestedOffset) {
        CrashReportCategory category = new CrashReportCategory(name);
        if (this.trackingStackTrace) {
            int size = category.fillInStackTrace(nestedOffset);
            StackTraceElement[] fullTrace = this.exception.getStackTrace();
            StackTraceElement source = null;
            StackTraceElement next = null;
            int traceIndex = fullTrace.length - size;
            if (traceIndex < 0) {
                LOGGER.error("Negative index in crash report handler ({}/{})", fullTrace.length, size);
            }
 
            if (fullTrace != null && 0 <= traceIndex && traceIndex < fullTrace.length) {
                source = fullTrace[traceIndex];
                if (fullTrace.length + 1 - size < fullTrace.length) {
                    next = fullTrace[fullTrace.length + 1 - size];
                }
            }
 
            this.trackingStackTrace = category.validateStackTrace(source, next);
            if (fullTrace != null && fullTrace.length >= size && 0 <= traceIndex && traceIndex < fullTrace.length) {
                this.uncategorizedStackTrace = new StackTraceElement[traceIndex];
                System.arraycopy(fullTrace, 0, this.uncategorizedStackTrace, 0, this.uncategorizedStackTrace.length);
            } else {
                this.trackingStackTrace = false;
            }
        }
 
        this.details.add(category);
        return category;
    }
 
    public static CrashReport forThrowable(Throwable t, String title) {
        while (t instanceof CompletionException && t.getCause() != null) {
            t = t.getCause();
        }
 
        CrashReport report;
        if (t instanceof ReportedException reportedException) {
            report = reportedException.getReport();
        } else {
            report = new CrashReport(title, t);
        }
 
        return report;
    }
 
    public static void preload() {
        MemoryReserve.allocate();
        new CrashReport("Don't panic!", new Throwable()).getFriendlyReport(ReportType.CRASH);
    }
}

引用的其他类

  • CrashReportCategory

    • 引用位置: 字段/构造调用/返回值
    • 关联成员: CrashReportCategory()
  • ReportType

    • 引用位置: 参数
  • SystemReport

    • 引用位置: 字段/构造调用/返回值
    • 关联成员: SystemReport()
  • LoggedChatMessage

    • 引用位置: 方法调用
    • 关联成员: System.arraycopy()
  • FileUtil

    • 引用位置: 方法调用
    • 关联成员: FileUtil.createDirectoriesSafe()
  • MemoryReserve

    • 引用位置: 方法调用
    • 关联成员: MemoryReserve.allocate()