lingochamp/FileDownloader · error · NoFieldException

isReusedDownloadedFile

Error message

isReusedDownloadedFile

What it means

isReusedDownloadedFile() is a base-class accessor in MessageSnapshot that throws NoFieldException because most snapshots (started, pending, progress, etc.) do not record whether the downloaded file was reused; only the completed/warn snapshots carry that flag. Throwing means the flag does not exist for this snapshot's status and the caller asked for data the message never had.

Solutions

  1. Call isReusedDownloadedFile() only when getStatus() == FileDownloadStatus.completed (or on snapshots whose class overrides it).
  2. Fix the internal update() conversion to avoid querying the reuse flag on snapshots that do not carry it.
  3. Track reuse yourself: record it when the completed callback delivers a snapshot where the call succeeds, and use the recorded value elsewhere.
  4. Wrap the call in a try-catch for IllegalStateException as a last resort when snapshot type cannot be determined statically.

Example fix

// before
boolean reused = snapshot.isReusedDownloadedFile(); // throws for progress snapshots

// after
boolean reused = snapshot.getStatus() == FileDownloadStatus.completed
    && snapshot.isReusedDownloadedFile();
Defensive patterns

Strategy: type-guard

Validate before calling

public static boolean hasReusedFlag(IMessageSnapshot s) {
    return s.getStatus() == FileDownloadStatus.completed;
}

Type guard

public static Boolean reusedDownloadedFileIfPresent(IMessageSnapshot s) {
    if (s.getStatus() != FileDownloadStatus.completed) return null;
    try {
        return s.isReusedDownloadedFile();
    } catch (IllegalStateException e) {
        return null; // snapshot class does not carry the flag
    }
}

Try / catch

boolean reused = false;
try {
    reused = snapshot.isReusedDownloadedFile();
} catch (IllegalStateException e) {
    // flag not present for this status; treat as not reused
    reused = false;
}

Prevention

When it happens

Trigger: Calling isReusedDownloadedFile() on a snapshot with a status other than completed (or the statuses whose concrete class overrides it); internally invoked from the update() path that re-inspects every snapshot with the full accessor set.

Common situations: Listener code checking reuse status in every callback instead of only in blockComplete/completed; logic that decides whether to skip re-downloading based on a snapshot of the wrong status; library upgrades that turned previously-null-returning accessors into throwing ones, exposing latent unconditional calls.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of lingochamp/FileDownloader@6237a8cac1 (2026-09-08). Data as JSON: /api/errors/95cde9f3d0691a53. Report an issue: GitHub.

Appendix: source

Thrown at library/src/main/java/com/liulishuo/filedownloader/message/MessageSnapshot.java:83

    @Override
    public long getLargeTotalBytes() {
        throw new NoFieldException("getLargeTotalBytes", this);
    }

    @Override
    public int getSmallSofarBytes() {
        throw new NoFieldException("getSmallSofarBytes", this);
    }

    @Override
    public int getSmallTotalBytes() {
        throw new NoFieldException("getSmallTotalBytes", this);
    }

    @Override
    public boolean isReusedDownloadedFile() {
        throw new NoFieldException("isReusedDownloadedFile", this);
    }

    @Override
    public String getFileName() {
        throw new NoFieldException("getFileName", this);
    }

    @Override
    public boolean isLargeFile() {
        return isLargeFile;
    }


    public interface IWarnMessageSnapshot {
        MessageSnapshot turnToPending();
    }

View on GitHub (pinned to 6237a8cac1)