{"record":{"id":"accbd3d25ed4e745","repo":"lingochamp/FileDownloader","slug":"connection-is-null-when-findetag","errorCode":null,"errorMessage":"connection is null when findEtag","messagePattern":"connection is null when findEtag","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"library/src/main/java/com/liulishuo/filedownloader/util/FileDownloadUtils.java","lineNumber":550,"sourceCode":"\n    public static boolean checkPermission(String permission) {\n        final int perm = FileDownloadHelper.getAppContext()\n                .checkCallingOrSelfPermission(permission);\n        return perm == PackageManager.PERMISSION_GRANTED;\n    }\n\n    public static long convertContentLengthString(String s) {\n        if (s == null) return -1;\n        try {\n            return Long.parseLong(s);\n        } catch (NumberFormatException e) {\n            return -1;\n        }\n    }\n\n    public static String findEtag(final int id, FileDownloadConnection connection) {\n        if (connection == null) {\n            throw new RuntimeException(\"connection is null when findEtag\");\n        }\n\n        final String newEtag = connection.getResponseHeaderField(\"Etag\");\n\n        if (FileDownloadLog.NEED_LOG) {\n            FileDownloadLog.d(FileDownloadUtils.class, \"etag find %s for task(%d)\", newEtag, id);\n        }\n\n        return newEtag;\n    }\n\n    // accept range is effect by  response code and Accept-Ranges header field.\n    public static boolean isAcceptRange(int responseCode, FileDownloadConnection connection) {\n        if (responseCode == HttpURLConnection.HTTP_PARTIAL\n                || responseCode == FileDownloadConnection.RESPONSE_CODE_FROM_OFFSET) return true;\n\n        final String acceptRanges = connection.getResponseHeaderField(\"Accept-Ranges\");\n        return \"bytes\".equals(acceptRanges);","sourceCodeStart":532,"sourceCodeEnd":568,"githubUrl":"https://github.com/lingochamp/FileDownloader/blob/6237a8cac174bcc916e4342b14ab1ab72a5768d4/library/src/main/java/com/liulishuo/filedownloader/util/FileDownloadUtils.java#L532-L568","documentation":"findEtag extracts the 'Etag' response header from an HTTP connection used for resumable downloads. It throws a RuntimeException if the connection is null, since a null connection is an internal programming error — a valid connection is required to read the Etag for breakpoint-resume validation.","triggerScenarios":"Calling FileDownloadUtils.findEtag(id, null) with a connection that failed to be created (e.g. FileDownloadConnection creation failed after connect) or was never assigned.","commonSituations":"Custom DownloadConnection implementation returning null on error; network layer failure swallowed upstream so the null connection propagates to findEtag; unit tests passing null stubs.","solutions":["Ensure the connection is non-null before calling: check the result of the connect/creation step and handle failures before reading headers.","If using a custom connection factory, never return null — throw a descriptive IOException instead.","Guard the call site with if (connection != null) and treat null as a retryable network failure."],"exampleFix":"// before\nString etag = FileDownloadUtils.findEtag(id, connection); // connection may be null\n\n// after\nif (connection == null) {\n    throw new FileDownloadNetworkException(\"connection failed, cannot read Etag\");\n}\nString etag = FileDownloadUtils.findEtag(id, connection);","handlingStrategy":"validation","validationCode":"if (connection == null) {\n    throw new IOException(\"download connection not established; cannot read Etag\");\n}\nString etag = FileDownloadUtils.findEtag(id, connection);","typeGuard":null,"tryCatchPattern":"try {\n    etag = FileDownloadUtils.findEtag(id, connection);\n} catch (RuntimeException e) {\n    // treat as network failure; retry or restart task without resume\n}","preventionTips":["Always null-check the connection returned by your connect step before header reads.","Make custom Connection factories throw instead of returning null.","Centralize connection creation so failures are handled in one place."],"tags":["android","http","etag","null-argument","filedownloader"],"backgroundTag":"null-argument","analyzedSha":"6237a8cac174bcc916e4342b14ab1ab72a5768d4","analyzedAt":"2026-09-08T23:50:48.168Z","contentChangedAt":"2026-09-08T23:50:48.168Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}