How can a Slack app communicate to the user why a slash command failed, and let the user edit the command? - error-handling

When an app fails to handle a Slack slash command, the text is brought back to allow the user to edit it and immediately send it again. I have a slash-command that searches, but might fail to find any results. In that case, I would like the user to immediately be able to modify their search. The Slack docs explain that I should always return a 200 HTTP status, but then Slack also erases the command and the user can't immediately try again. When I tried to respond with a 404 status, the users get an alarming message like failed with the error "http_client_error". Is there a way to fail but also provide a custom message to the user why?

Yes, but you must not use HTTP status codes to community a failed search.
Just always return HTTP OK 200 and then add a response message telling the user what went wrong. You can do that by directly replying to the request from Slack within 3 seconds, or alternatively by sending a message to the response_url.
This is also clearly expressed in the offical documentation for slash commands:
Sending Error Responses
There are going to be times when you need to let the user know that something went wrong - perhaps the user supplied an incorrect text parameter alongside the command, or maybe there was a failure in an API being used to generate the command response.
It would be tempting in this case to return an HTTP 500 response to
the initial command, but this isn't the right approach. The status
code returned as a response to the command should only be used to
indicate whether or not the request URL successfully received the data
payload - while an error might have occurred in processing and
responding to that payload, the communication itself was still
successful. (Source)
As far as I know it is not possible to signal Slack that the user should be able to edit his last command though.

Related

what should be HTTP status code if resource is not available for requested action?

I am developing a RESTful API. I am confused about setting HTTP status code in this particular scenario. I am not sure what status code should I (server) return.
Let's say my app has a follow user functionality, if I am already following a user and again I send follow request for the same user id then in this case what should be the HTTP status code from server. The status code will be followed by an error message saying something like: "already following the user."
Similar scenario can be considered for unfollow user functionality, if I am not following an user "A", still I send request to unfollow user "A", then what HTTP status code should server return with error message something like "not following user to unfollow"
Certainly 200 response code doesn't seem to be appropriate to me here? or does it?
Please forgive me if I have posted the question at wrong stack exchange site, I posted it in stackoverflow site just because it is related to REST APIs.
EDIT
From client side user needs to send POST request to the URL:
http://www.myserver.com/api/follow/10
along with other necessary parameters ( like API keys, proper headers, etc) which are used for authentication before serving the requests at server side.
similar URL for unfollow action is:
http://www.myserver.com/api/unfollow/10
Right now, I am sending HTTP status code 200 in response if the client sends follow request, let's say, for user id 10 even if he/she is already following the user with id 10. In this case,along with status code (200) I am sending message similar to "already following the user"
Somehow I feel this is not convincing as no resource is created/updated it should return the error message with proper status code something other than 200, may be one from 4XX, not sure.
422 Unprocessable Entity
422 seems to be the proper HTTP status code in this use case.
The description of 422 says:
The 422 (Unprocessable Entity) status code means the server understands the content type of the request entity (hence a 415(Unsupported Media Type) status code is inappropriate), and the syntax of the request entity is correct (thus a 400 (Bad Request) status code is inappropriate) but was unable to process the contained instructions.
The answer depends on your API. You're describing the API in terms of "follow user X" or "unfollow user Y". That makes me think you might be approaching your API design in an RPC style rather than focusing on resources.
If your API uses REST including the HATEOAS principle, then error codes from the 4xx range may be appropriate (but I would recommend against it in this case, see below). In very short: HATEOAS means that your resources provide links to possible "actions". You can read more about it here: http://restcookbook.com/Basics/hateoas/
Apart from that, it seems a good idea to design your API "fault tolerant", i.e. expect the same request sent multiple times (e.g. because users are impatient and click again and again, or the browser crashed and is restarted and reopens all previous tabs, or...).
My personal opinion and recommendation is the following:
follow user X: Your implementation should check if it needs to add the new follower or not. Regardless, if the user is already following or not, send back HTTP status 201 (created) and add the "Location" HTTP header pointing at the resource.
unfollow user X: Your implementation should check if it needs to delete the follower or not. Regardless, if the user is already removed from the followers or not, send back HTTP status 200 (OK).
The general idea is, if a client requests something to be a certain way and that is already the case, the server has two options: Either it responds to the client "The result you wish is already in place. Therefore your request is invalid." or the server can respond "The result you wish is already in place. You have everything you need.".
Going for the second option makes the API more tolerant and helps with idempotency (see http://restcookbook.com/HTTP%20Methods/idempotency/).
I think djlauk's answer covers a lot, but I want to give a little different approach and add some information:
Do not use verbs in the URI
I would not use POST on /follow/ respectively /unfollow/ URIs because this is not very RESTful see this SO question: Why does including an action verb in the URI in a REST implementation violate the protocol? and escpacially this SO answer: How to create REST URLs without verbs?
Do use the correct HTTP verbs for the actions
What you want to do is a creation of an entity ("follow") so for that you can use the HTTP verbs POST or PUT and afterwards the deletion of that entity ("unfollow") where DELETE would be the right fit.
My approach for your API:
I would do the following:
(The first two examples are just for explaining the structure, you don't have to implement them if you don't need them.)
This does get you the user "robert":
GET http://www.myserver.com/api/users/robert/
response: #200
This does get you the users "robert" is following:
GET http://www.myserver.com/api/users/robert/following/
response: #200
And this is how you let "robert" follow "rahul":
PUT http://www.myserver.com/api/users/robert/following/rahul
response: #200
If you send this request again you get the same response:#200 because PUT is idempotent and this is how it should behave (see (2))
When you now want to let "robert" unfollow "rahul" you send:
DELETE http://www.myserver.com/api/users/robert/following/rahul
response: #200
If you send the DELETE request again you get a little different response a #404 , but this is HTTP standard and the clients should understand this.
For the regular answer codes of HTTP methods I can also recommend this source: restapitutorial.com
I would use some of the following:
System.Net.HttpStatusCode.ServiceUnavailable;
System.Net.HttpStatusCode.MethodNotAllowed;
System.Net.HttpStatusCode.BadRequest;
Better if it is one of the first two.
Certainly 200 response code will not work in this situation.
following are the groups in HTTP Status Code:
1xx Informational
2xx Success
3xx Redirection
4xx Client Error
5xx Server Error
Certainly you need to use 4xx.
I think for the condition that you have described here, you can use any of the following:
405 Method Not Allowed
A request was made of a resource using a request method not supported by that resource; for example, using GET on a form which requires data to be presented via POST, or using PUT on a read-only resource.
400 Bad Request
The server cannot or will not process the request due to something that is perceived to be a client error
409 Conflict
Indicates that the request could not be processed because of conflict in the request, such as an edit conflict in the case of multiple updates.
More details are available here:
http://en.wikipedia.org/wiki/List_of_HTTP_status_codes

which tokens/codes/ids actually need to be exchanged for google oauth

i'm trying to follow the example code on google's website here, but it seems a little broken - the javascript references getting a list of people from the server, but in the server-side code there's no reference to calling those functions of the api, it just returns an HTTP status code and a text status, so i'm wondering if there's a step missing and i'm exchanging the wrong code at the wrong time.
my current flow is
login button button clicked, magic happens, my callback gets passed an object with a whole bunch of properties in it
I take the code property from that object, and post it back to my server in an ajax request
on my server, i run the following python, where auth_code_from_js is the data of my post request:
oauth_flow = client.flow_from_clientsecrets('client_secrets.json', scope='')
credentials = oauth_flow.step2_exchange(auth_code_from_js)
python throws a FlowExchangeError with the message invalid request and no other useful information
am i missing a step? is that initial 'code' property what i'm supposed to be passing in to the 'step2_exchange' method?

Use AWS S3 success_action_redirect policy with XHR

I'm using signed POST to upload file directly to amazon S3. I had some trouble with the signature of the policy using PHP but finally fixed it and here is the sample of code.
This xhr request is send in javascript and I'm waiting for an answer from amazon. At first I was using success_action_status setting it to 201 to get the XML response.
What I'd like to do is using the success_action_redirect to call a script on my server to create a record in the database.
The reason why is that I could create the record in the database and if anything wrong happen at this stage I can return an error message directly at this point. Also it saves me another ajax request to my server.
So I've tried to set this up specifying the success_action_redirect to http:\\localhost\callback.php where I have a script that is waiting for some parameters.
But it looks like this script is never called and the response of the xhr.send() is empty.
I think it's a cross-browser issue and I'm wondering if it would be possible to use jsonp somehow to pass-by this?
Any ideas?
UPDATE
Apparently xhr is following redirect natively so it should work but when I specified the success_action_redirect it returns error Server responded with 0 code.
At first I thought it was because the redirect URL was on my local server so I've changed it to an accessible server but no chance.
Anyone knows why it's returning this error message?
I also run into this problem. It seems like nobody has a solution to this like this
maybe the best workaround i have found is something like this.
It seems thet the only workaround includes a second xhr-request to execute the callback manually. therefore the
success_action_status
should be used. Witht his you will get a 201 response if the upload was successful and you can start a second request for the actual callback. For me it looks like the only possible solution at the moment.
Any other solutions?

Dojo informative message sent after xhrPost

Let's say that a request is sent to server via xhrPost and server finds that request needs more information to be processed (for example a variable is missing), so, a response is sent back to client informing that request may have not been completely processed and this message is shown in a dialog box.
I was doing it sending from server an HTTP 202 status code, which I believe is not correct, and treating it on load function, where this message was displayed on a dialog box. But if I respond with some HTTP error code (ex: 400) the error is displayed in console (Note: in this case the message is treated in error function), as well as in my dialog box.
What is the best and correct way to do it?
Note that it is called a load handler, not a success handler.
The load hander is for valid, well formatted responses. These can contain a verity of status codes generated by your server side app that indicates success, failure, or something in between.
The error is just that, the server blew up while trying to process the request and whatever you get back is probably not something your widget was written to expect. For this reason, I recommend using the same error handler across your whole app.
The dojo documentation states:
Sometimes xhrGet calls will fail. Often these are 404 errors or server errors such as 500. The error parameter is another callback function that is only invoked when an error occurs. This allows you to control what happens when an error occurs without having to put a lot of logic into your load function to check for error conditions. The first parameter passed to the error function is a JavaScript Error object indicating what the failure was. Dojo doc

Which Http Status code to return when user provided data fails validation in Web Service?

When the user enters data and submits that data, we pass it to the server using and XMLHttpRequest. But, if that data fails validation, we have to return a 400 level status code. I thought the appropriate code would be 403. However, my colleague doesn't agree but doesn't know which to use.
Which one would you use?
Thanks!
400 would be more correct, i.e. the request contained invalid data. 403 would imply some kind of permisions error, i.e. the request was well formed and correct but the action was not allowed. If i was writing code to consume a web service and i got a 403 error it would never occur to me that it was because i was sending invalid data, it would be very confusing indeed.