-
Notifications
You must be signed in to change notification settings - Fork 325
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
Improve error handling for window.ipfs #455
Comments
I also noticed this dev difficulty when reading the window.ipfs docs, I agree we should provide some common Error type or utils to detect them. const accessErrorSymbol = Symbol.for('IPFS Access Error') // or smth
const isAccessError = error => accessErrorSymbol in error
function AccessError(message, permission) {
const error = new Error(message)
error[accessErrorSymbol] = true
error.permission = permission
return error
}
// companion usage:
if (access popup is closed)
throw new AccessError('Failed to obtain access response to ${permission} at ${scope}', permission)
// user-land:
try {
const { CID } = await ipfs.files.add(buf)
await ipfs.pubsub.publish(friendPool, CID)
} catch (err) {
if (isAccessError(err) && err.permission.match(/pubsub/)) {
return // non-critical error, continue user flow
} else {
// app-specific handling
}
} I think it's good practice for libraries to use Symbols to prevent naming collisions with consumers but we could alternatively do something else. Because of the security concerns with revealing the availability of |
Hm.. how about something more explicit: function IpfsApiAccessError(message, permission, scope) {
this.name = 'IpfsApiAccessError';
this.message = message;
this.permission = permission;
this.scope = scope; // for completeness
this.stack = (new Error()).stack;
}
IpfsApiAccessError.prototype = new Error; // makes 'instanceof Error' work as well It makes error-type-check less elaborate ( } catch (err) {
if (err instanceof IpfsApiAccessError && err.permission.match(/pubsub/)) { Are there any red flags to this approach?
Yes, that is the plan, but we should tackle #451 in separate PR :) |
Yep, I'm totally on board. Symbols don't provide much value over this approach and it's much simpler. How about we take it a step further and: class IpfsApiAccessError extends Error {
constructor (message, permission, scope) {
super(message)
this.permission = permission;
this.scope = scope; // for completeness
}
} Extending Error gives us built-in I'm happy to implement whatever we conclude here. |
Sounds good, give it a try in a PR :) |
Hey! Yes, we can do better with detecting this flavor of error. I'm sorry I didn't see this issue until after @JonKrone had submitted a PR. There's a few things at play here: An FYI an ACL error is created "server side" so needs to be serialized to be passed back to the caller.
It is influenced by So if on the server you were to create an error: const err = new Error('User denied access to ipfs.files.add')
err.output = { payload: { isIpfsProxyAclError: true, scope, permission } } i.e. here Then on the client side you should be able to: try {
ipfs.files.add(/* ... */)
} catch (err) {
if (err.isIpfsProxyAclError) {
// Error was an IPFS Proxy ACL error
console.log('Failed to access', err.scope, err.permission)
}
} For the sake of simplicity, I'd leave it as that (i.e. not implement a custom subclass). |
|
Question from IRC:
For a better context, we currently suggest this in
docs/window.ipfs.md
:Initial ideas:
The text was updated successfully, but these errors were encountered: