Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Detect why filesystem call fails #326

Open
ersimont opened this issue Mar 24, 2021 · 6 comments
Open

feat: Detect why filesystem call fails #326

ersimont opened this issue Mar 24, 2021 · 6 comments

Comments

@ersimont
Copy link

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

@thomasvidas thomasvidas transferred this issue from ionic-team/capacitor Mar 25, 2021
@thomasvidas thomasvidas added triage and removed triage labels Mar 25, 2021
@thomasvidas
Copy link
Contributor

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
}

@ersimont
Copy link
Author

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.

@jcesarmobile
Copy link
Member

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.

@hf-farmqa
Copy link

hf-farmqa commented Jul 20, 2021

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() 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.

@ecc521
Copy link

ecc521 commented Jun 17, 2024

If #2136 is a duplicate of this issue then iOS and Web tags should be added to this issue.

@Alex-Giannetto
Copy link

I think we could take inspiration from the Cordova File Plugin, which has error codes that make it easy to handle different exceptions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants