{"record":{"id":"8310e89c76511181","repo":"didi/DoKit","slug":"leaktraceasfakeexception-can-only-be-called-when","errorCode":null,"errorMessage":"leakTraceAsFakeException() can only be called when leakFound is true","messagePattern":"leakTraceAsFakeException\\(\\) can only be called when leakFound is true","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"Android/dokit-leakcanary/src/main/java/com/squareup/leakcanary/AnalysisResult.java","lineNumber":110,"sourceCode":"   * <pre>\n   * * com.foo.WibbleActivity has leaked:\n   * * GC ROOT static com.foo.Bar.qux\n   * * references com.foo.Quz.context\n   * * leaks com.foo.WibbleActivity instance\n   * </pre>\n   *\n   * <p>Will turn into an exception with the following stacktrace:\n   * <pre>\n   * java.lang.RuntimeException: com.foo.WibbleActivity leak from com.foo.Bar (holder=CLASS,\n   * type=STATIC_FIELD)\n   *         at com.foo.Bar.qux(Bar.java:42)\n   *         at com.foo.Quz.context(Quz.java:42)\n   *         at com.foo.WibbleActivity.leaking(WibbleActivity.java:42)\n   * </pre>\n   */\n  public @NonNull RuntimeException leakTraceAsFakeException() {\n    if (!leakFound) {\n      throw new UnsupportedOperationException(\n          \"leakTraceAsFakeException() can only be called when leakFound is true\");\n    }\n    LeakTraceElement firstElement = leakTrace.elements.get(0);\n    String rootSimpleName = classSimpleName(firstElement.className);\n    String leakSimpleName = classSimpleName(className);\n\n    String exceptionMessage = leakSimpleName\n        + \" leak from \"\n        + rootSimpleName\n        + \" (holder=\"\n        + firstElement.holder\n        + \", type=\"\n        + firstElement.type\n        + \")\";\n    RuntimeException exception = new RuntimeException(exceptionMessage);\n\n    StackTraceElement[] stackTrace = new StackTraceElement[leakTrace.elements.size()];\n    int i = 0;","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/didi/DoKit/blob/626827cddb2feb2f3aee87a52a064b4e5ca2bed4/Android/dokit-leakcanary/src/main/java/com/squareup/leakcanary/AnalysisResult.java#L92-L128","documentation":"Thrown by AnalysisResult.leakTraceAsFakeException() when it is invoked on an AnalysisResult whose leakFound field is false. The method fabricates a RuntimeException whose stack trace mirrors the leak trace (leaking class <- holder chain); that only makes sense when analysis actually found a leak. It is a guard against calling a result accessor on a non-leak result.","triggerScenarios":"Calling analysisResult.leakTraceAsFakeException() without first checking analysisResult.leakFound. Typical in code that unconditionally converts every analysis result into an exception for crash reporting or test assertions, including results that reported NO_LEAK or failed analysis.","commonSituations":"Integrating LeakCanary results into a crash reporter and forgetting the leakFound branch. Writing unit tests over AnalysisResult that exercise the fake-exception path for all results. Handling AnalysisResult.failureText / retention-visibility results where leakFound is false.","solutions":["Check result.leakFound before calling leakTraceAsFakeException()","Branch on the full result state: leakFound, failureText (analysis failed) before touching leakTrace","If you need the leak trace outside the exception, access result.leakTrace directly (also only when leakFound is true)"],"exampleFix":"// before\nRuntimeException fake = result.leakTraceAsFakeException();\n\n// after\nif (result.leakFound) {\n  RuntimeException fake = result.leakTraceAsFakeException();\n  crashReporter.report(fake);\n} else if (result.failureText != null) {\n  Log.e(\"LeakCanary\", result.failureText);\n}","handlingStrategy":"validation","validationCode":"if (result.leakFound) { RuntimeException fake = result.leakTraceAsFakeException(); }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always branch on result.leakFound and result.failureText before accessing leak-specific accessors","Treat leakTraceAsFakeException as available only on positive results"],"tags":["leakcanary","android","guard-clause","java"],"backgroundTag":null,"analyzedSha":"626827cddb2feb2f3aee87a52a064b4e5ca2bed4","analyzedAt":"2026-08-14T12:45:58.758Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}