feat: Detect why filesystem call fails
Feature Request
I would like to write specific handlers when the user intentionally denies my app access to the filesystem, letting them know that it's required for their requested operation to complete.
Description
Platform(s)
Android, since that's the only one I'm using so far :)
Preferred Solution
It would be great it the promise rejection had a reliable CODE field or similar.
Alternatives
I can check the rejection string currently to see if it matches the text "Unable to do file operation, user denied permission request". But that doesn't seem like the kind of thing that would be guaranteed to stay the same forever. Nor is it documented.
Additional Context
Could you elaborate on the CODE suggestion? Like an Error code? And regardless of how the permission fails, wouldn't you still handle that in the same way?
try {
await Filesystem.readFile();
} catch (e) {
// Handle rejection here
}
Sure thing. I meant something like:
try {
await Filesystem.readFile();
} catch (e) {
if (e.code === FilesystemErrorCode.PERMISSION_DENIED) {
// show an appropriate message encouraging the user to grant permission next time
} else {
throw e;
}
}
There could of course be any number of special cases to handle different error codes in different ways.
Probably not exactly what you want, but you have the checkPermissions() method that will tell you if they are granted (everything ok), prompt (you have never asked for the permissions), prompt-with-rationale (the user has denied permissions at least once), denied (user deny and checked never ask again, so nothing you can do at this point).
Anyway, filesystem permissions are only needed when you try to read/write in public folders, which is not possible on Android 11+, for the app locations you should be able to read/write without permission.
An error code as more standard part of the Capacitor error object would also solve a problem I've run into with how the IOS plugin reports errors back up the chain.
For example, calling the FileSystem.stat(<StatOptions>) API for a file or folder path that does not exist. The Web and Android plugins check for existence and then return a hard-coded, albeit different, string but the IOS plugin just has a generic try/catch and if something happens it fails the call with a localized error message that presumably comes from the native device.
Since all we have to work with when catching an exception at the JS level is the raw error message, the only thing we can really do to check that it contains some special hopefully-consistent string to contextualize the error and deal with it appropriately.
Ex:
try {
return Filesystem.stat({
directory: FilesystemDirectory.Data,
path: 'this/does/not/exist.404',
});
} catch (err) {
if (err && (err.message.indexOf('File does not exist') >= 0 || err.message.indexOf('.... <repeat for known messages> )) {
// Do something now that you know it is a File-Not-Found
} else {
// Do something for some other error type, maybe you've got special logic for certain other cases
}
}
This error message checking is not entirely feasible if you need to code for any/all translated IOS messages. As ersimont pointed out they aren't documented in Capacitor and probably guaranteed never to change.
Having a context/language-insensitive error code (or some other consistent mechanism) as part of the Capacitor error contract would then solve this problem. It wouldn't necessarily have to handle any/all errors that could ever be tossed out by a native device, but a set of pretty well know cases like 'file not found' or 'permissions denied' would go along way I think.
All of that being said, I'm not an expert or even deeply familiar with the Capacitor libs so maybe there is a another simple way to account for this problem. If so, then (egg on my face) I'd be very glad to know about it.
If #2136 is a duplicate of this issue then iOS and Web tags should be added to this issue.
I think we could take inspiration from the Cordova File Plugin, which has error codes that make it easy to handle different exceptions.
Hey everyone, this issue has been addressed in @capacitor/filesystem plugin, from version 7.1.0 - Addition of several error codes, as per the docs.
If you discover new issues, please open them in the new repository.
Will be closing this issue. Thank you!
Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of the plugin, please create a new issue and ensure the template is fully filled out.