{"record":{"id":"85e532153b1691d6","repo":"MuntashirAkon/AppManager","slug":"ioexception-remote-err-msg-throwable","errorCode":null,"errorMessage":"IOException(REMOTE_ERR_MSG, throwable)","messagePattern":"IOException\\(REMOTE_ERR_MSG, throwable\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"libcore/io/src/main/java/io/github/muntashirakon/io/IOResult.java","lineNumber":34,"sourceCode":"\n    private final Object val;\n\n    IOResult() {\n        val = null;\n    }\n\n    IOResult(Object v) {\n        val = v;\n    }\n\n    @Override\n    public void writeToParcel(Parcel dest, int flags) {\n        dest.writeValue(val);\n    }\n\n    void checkException() throws IOException {\n        if (val instanceof Throwable) {\n            throw new IOException(REMOTE_ERR_MSG, (Throwable) val);\n        }\n    }\n\n    void checkErrnoException() throws ErrnoException, RemoteException {\n        if (val instanceof ErrnoException) {\n            throw (ErrnoException) val;\n        } else if (val instanceof Throwable) {\n            Throwable th = (Throwable) val;\n            throw (RemoteException) new RemoteException(th.getMessage()).initCause(th);\n        }\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    <T> T tryAndGet() throws IOException {\n        checkException();\n        return (T) val;\n    }\n","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/libcore/io/src/main/java/io/github/muntashirakon/io/IOResult.java#L16-L52","documentation":"IOResult is a Parcelable wrapper for a value returned from a remote IFileSystemService call; if that value is actually a Throwable thrown remotely, checkException() rethrows it locally as IOException(REMOTE_ERR_MSG, cause). This is how the library propagates exceptions that occurred in a remote file-system service process back to the caller.","triggerScenarios":"Calling FileSystemManager methods backed by a remote binder (createRemote) whose remote operation threw any Throwable (e.g. an IOException or RuntimeException inside the service); the stub returns it in the IOResult and tryAndGet calls checkException(), which rethrows it wrapped.","commonSituations":"Remote service crashes or throws while accessing files the service process cannot reach; binder calls across process boundaries where the remote side lacks permissions; dead or misbehaving IFileSystemService implementations.","solutions":["Inspect getCause() of the IOException to find the original remote exception","Fix the root cause in the remote service (permissions, path validity) or ensure it returns ErrnoException-based failures instead of raw Throwables","Check that the remote service process has the same or greater file access rights than expected"],"exampleFix":"// before\ntry { fm.getFile(path).delete(); } catch (IOException e) { /* opaque */ }\n// after\ntry { fm.getFile(path).delete(); }\ncatch (IOException e) {\n    Throwable remote = e.getCause();\n    Log.e(TAG, \"remote op failed\", remote); // diagnose actual remote failure\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"if (ioException.getCause() instanceof ErrnoException) { ErrnoException errno = (ErrnoException) ioException.getCause(); /* branch on errno */ }","tryCatchPattern":"try { result = remoteOp(); } catch (IOException e) { Throwable c = e.getCause(); log(\"remote failure\", c); /* rethrow as domain error or retry */ }","preventionTips":["Always inspect getCause() on IOExceptions from remote FileSystemManager calls","Give the remote service process the permissions it needs before binding","Distinguish remote ErrnoException causes from other throwables in error handling"],"tags":["android","ipc","binder","remote-exception","io"],"backgroundTag":"upstream-api-error","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}