Closed mjdavidson closed 1 year ago
Hi @mjdavidson, thanks for asking the question!
In this case, you can customize your app's behavior by adjusting a bit more details of the underlying HTTPReceiver: https://slack.dev/bolt-js/concepts#error-handling More specifically, handling the exception in processEventErrorHandler
and returning some message like you usually do with ack()
method and/or performing a web API call such as chat.postMessage/chat.postEphemeral or whatever. If you're using SocketModeReceiver, the receiver supports the same set of error handlers too.
Slash command patterns would be quite simple. Just sending things to tell in the response body works. However, for other patterns, how to handle the unexpected error can be a bit more complex.
For instance, in the case of Events API request patterns, your app cannot directly respond to it (imagine events like channel_left). In this case, your app needs to go with more indirect way such as opening a DM with the user and then telling what happened. Perhaps, you can say "To use this app, please go through the installation process from here (link)" or something like that.
As for user interaction patterns such as button clicks on a channel message, a good way to go would be using response_url, which is the underlying mechanism of respond()
utility. You can use the URL to send notifications to the place where the interaction happened even when the authorize fails. You can use the processEventErrorHandler
for this too, but an easier way is to use app.error
handler as the handler provides respond
utility. If you're interested in more details, what we do in the official Java SDK may be helpful for learning what to do: https://github.com/slackapi/java-slack-sdk/blob/v1.27.1/bolt/src/main/java/com/slack/api/bolt/middleware/builtin/MultiTeamsAuthorization.java#L205-L233
I hope this was helpful to you!
Hey @seratch, thanks for your quick response! We are using the ExpressReceiver
, so the processEventErrorHandler
doesn't exist. All I really want is a way to send a message if there is no authorization.
@mjdavidson If you're fine to upgrade bolt-js version, the handler exists for ExpressReceiver too! https://github.com/slackapi/bolt-js/blob/%40slack/bolt%403.12.2/src/receivers/ExpressReceiver.ts#L181
OK great! I have upgraded to the latest bolt-js version, but still am a little unsure as to how I should be sending a message back to the user that they need to re-authenticate? The java sdk seems to have access to more properties inside the authorize function?
@mjdavidson
If you go with response_url (respond()
method in app.error
), the URL is already associated with the channel where the user is now. So, just sending an ephemeral message using the URL works. This is what the Java SDK does. Inside processEventErrorHandler
, you cannot use respond()
method, but you can easily implement the same. It actually performs an HTTP POST request this way: https://github.com/slackapi/bolt-js/blob/@slack/bolt@3.12.2/src/App.ts#L1553-L1556
If you want to start a DM with the user, your code needs to extract the user ID from the body
data structure. This may be a bit challenging because the payload data structure can vary.
OK I'll give app.error
a go and let you know how I get on. Cheers!
Please note that app.error
handler is not capable of eliminating the "dispatch_failed" error on the end-user side. If you're fine to send a message while still having the "dispatch_failed" error, app.error
works. Otherwise, you still need to do something with processEventErrorHandler
.
Also, if your app needs to resolve this issue only for slash command invocations, just sending HTTP response body with your message in processEventErrorHandler
better works for you.
Hope you'll figure out the best way to go!
ahhhhh @seratch you're a legend, finally feel like i've made some progress on this issue!! thanks so much <3 <3 <3
@seratch one last thing, I've handled errors in dispatchErrorHandler
, processEventErrorHandler
, and unhandledRequestHandler
using the code from the example you linked above, I've also implemented app.error
to send a specific error for the AuthorizationError
case and also a generic message for all other errors. I feel like I've covered all the bases and I get the correct error back in Slack.
I still get failed with the error "operation_timeout"
though, where have I gone wrong?
@seratch looks like it works if you use unhandledRequestTimeoutMillis: 2000
, not really sure why that happens
@mjdavidson Your app must return 200 OK HTTP response within 3 seconds. The ack()
method does this for you under the hood. If you don't do so, the timeout error can occur. The reason why the unhandledRequestTimeoutMillis: 2000 works for you is perhaps your unhandledRequestHandler sends 200 OK anyways in 2.x seconds in the case.
It also works! but I would suggest:
app.error
still raise the exception after sending a message using response_urlprocessEventErrorHandler
and then sends 200 OK HTTP response if the code is expectedAgain, as I mentioned above, with bolt-js, app.error
is not capable of acknowledging requests. If you use app.error
for using response_url, acknowledgement needs to be done in processEventErrorHandler
error handler.
Thanks again mate!
Description
When using the authorize function as seen here, what should be done when an error is thrown?
throw new Error('No matching authorizations');
At the moment my code looks the same as the example in the docs, but when an authorization isn't found the app blows up and says
failed with the error "dispatch_failed"
. I would like to prompt the user to re-authorize.I haven't been able to find an example in the documentation that handles the case when an authorization doesn't exist
What type of issue is this? (place an
x
in one of the[ ]
)Requirements (place an
x
in each of the[ ]
)Bug Report
Filling out the following details about bugs will help us solve your issue sooner.
Reproducible in:
package version: 3.8.1
node version: 16.14.0
OS version(s): macOS Ventura
Steps to reproduce:
Expected result:
Ask to re-authenticate
Actual result:
Receive
failed with the error "dispatch_failed"