lingochamp/FileDownloader · error · NoFieldException

getLargeTotalBytes

Error message

getLargeTotalBytes

What it means

getLargeTotalBytes() is one of the accessors MessageSnapshot's base class deliberately implements by throwing NoFieldException. Only snapshots that carry the large-file total size (progress/connected/error/completed large snapshots) override it. Throwing means the snapshot's status has no 'total bytes' field, so the caller queried a field that does not exist for this message.

Solutions

  1. Guard with getStatus()/isLargeFile() before calling getLargeTotalBytes(); read it only for progress or connected snapshots of a large file.
  2. Fix the internal update/handoverMessage conversion to select the correct accessor for the concrete snapshot class.
  3. Cache the total bytes returned during the progress callback and reuse the cached value for other statuses.
  4. Verify the snapshot was built through MessageSnapshot.CREATOR so the status-appropriate subclass is instantiated.

Example fix

// before
long total = snapshot.getLargeTotalBytes(); // throws for warn/started snapshots

// after
long total = 0;
if (snapshot.getStatus() == FileDownloadStatus.progress
        || snapshot.getStatus() == FileDownloadStatus.connected) {
    total = snapshot.getLargeTotalBytes();
}
Defensive patterns

Strategy: type-guard

Validate before calling

public static boolean hasLargeTotal(IMessageSnapshot s) {
    return s.isLargeFile()
        && (s.getStatus() == FileDownloadStatus.progress
            || s.getStatus() == FileDownloadStatus.connected);
}

Type guard

public static boolean exposesTotalBytes(IMessageSnapshot s) {
    byte st = s.getStatus();
    return st == FileDownloadStatus.progress
        || st == FileDownloadStatus.connected;
}
// usage: long total = exposesTotalBytes(snap) ? snap.getLargeTotalBytes() : cachedTotal;

Try / catch

long total;
try {
    total = snapshot.getLargeTotalBytes();
} catch (IllegalStateException e) {
    total = cachedTotalBytes; // value remembered from progress callback
}

Prevention

When it happens

Trigger: Calling getLargeTotalBytes() on a snapshot whose status is started, warn, pending (small variant), retry, or similar; internally this is reached from the update() and handoverMessage() paths that translate a status-change snapshot without dispatching on its type.

Common situations: Progress UI code reading total bytes in a 'started' or 'warn' callback; code assuming every snapshot has total/sofar fields; Parcelable deserialization producing a snapshot class that does not hold the field and then being inspected; library versions where the accessor was moved from a concrete class to a throwing base default.

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/726788ca5b689c71. Report an issue: GitHub.

Appendix: source

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

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

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

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

    @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

View on GitHub (pinned to 6237a8cac1)