I am using Stripe gem in my rails application, it's working fine in the development environment but in my production environment getting an exception.
Stripe::APIError: (Status 409) with message There is currently another in-progress request using this Idempotent Key (that probably means you submitted twice, and the other request is still going through).
How can I rescue this or handle this exception?
Any help would be appreciated.
The retry logic is supposed to be for when your application doesn't know Stripe's response, primarily during network issues likes timeouts. In this case your server received a response from stripe and one of two things could be happening. Either you're retring the same event that is currently in progress /or/ the event in progress is actually different than the one you're trying but given some issue in your application stack you actually chose the same indempotency token for two api requests.
For further details please read this link :- https://stripe.com/docs/api/idempotent_requests
Related
I have a rails api using devise-token-auth. Recently I was on really spotty/slow Wifi and I noticed I was getting 401's from my app. My theory is that the refreshing auth token is either being lost and delayed by the bad network. That being said, I'm having a hard time reproducing the bug itself.
Three primary questions:
Could a spotty Wifi/network connection lead to 401s, due to loss or delay of the new auth-token. And if this is the case, is there a way to recover without needing the user to log back in.
How to reproduce such an environment, so I can debug this scenario.
I was able to reproduce it by delaying the server response using a debugger. In my case, this happens when I enable change_headers_on_each_request config, so when the response which carries the new tokens fails the next responses throw 401 code.
I recently sent an issue to the gem explaining this and asking how can I handle this situation on the frontend.
Assume following scenario:
Client is sending HTTP POST to server
Request is valid and
have been processed by server. Data has been inserted into database.
Web application is responding to client
Client meets timeout
and does not see HTTP response.
In this case we meet situation where:
- client does not know if his data was valid and been inserted properly
- web server (rails 3.2 application) does not show any exception, no matter if it is behind apache proxy or not
I can't find how to handle such scenario in HTTP documentation. My question are:
a) should client expect that his data MAY be processed already? (so then try for example GET request to check if data has been submitted)
b) if not (a) - should server detect it? is there possibility to do it in rails? In such case changes can be reversed. In such case i would expect some kind of expection from rails application but there is not...
HTTP is a stateless protocol: Which means by definition you cannot know on the client side that the http-verb POST has succeeded or not.
There are some techniques that web applications use to overcome this HTTP 'feature'. They include.
server side sessions
cookies
hidden variables within the form
However, none of these are really going to help with your issue. When I have run into these types of issues in the past they are almost always the result of the server taking too long to process the web request.
There is a really great quote to that I whisper to myself on sleepless nights:
“The web request is a scary place, you want to get in and out as quick
as you can” - Rick Branson
You want to be getting into and out of your web request in 100 - 500 ms. You meet those numbers and you will have a web application that will behave well/play well with web servers.
To that end I would suggest that you investigate how long your post's are taking and figure out how to shorten those requests. If you are doing some serious processing on the server side before doing dbms inserts you should consider handing those off to some sort of tasking/queuing system.
An example of 'serious processing' could be some sort of image upload, possibly with some image processing after the upload.
An example of a tasking and queuing solution would be: RabbitMQ and Celery
An example solution to your problem could be:
insert a portion of your data into the dbms ( or even faster some NoSQL solution )
hand off the expensive processing to a background task.
return to the user/web-client. ( even tho in the background the task is still running )
listen for the final response with ( polling, streaming or websockets) This step is not a trivial undertaking but the end result is well worth the effort.
Tighten up those web request and it will be a rare day that your client does not receive a response.
On that rare day that the client does not receive the data: How do you prevent multiple posts... I don't know anything about your data. However, there are some schema related things that you can do to uniquely identify your post. i.e. figure out on the server side if the data is an update or a create.
This answer covers some of the polling / streaming / websockets techniques you can use.
You can handle this with ajax and jQuery as the documentation of complete callback explains below:
Complete
Type: Function( jqXHR jqXHR, String textStatus )
A function to be called when the request finishes (after success and error callbacks are executed). The function gets passed two arguments: The jqXHR (in jQuery 1.4.x, XMLHTTPRequest) object and a string categorizing the status of the request ("success", "notmodified", "error", "timeout", "abort", or "parsererror").
Jquery ajax API
As for your second question, is their away to handle this through rails the answer is no as the timeout is from the client side and not the server side however to revert the changes i suggest using one of the following to detect is the user still online or not
http://socket.io/
websocket-rails
I'm using pusher gem to manipulate my front-end from an external API. It works fine, no problem with that.
But the thing I wonder is if there is a possibility to use push notifications at the back-end of my application? I spent a serious amount of time investigating this but couldn't find something useful.
Let me summarize:
I have an application and another API application which is tightly interacting with other. Sometimes I want to use my API to send notification to my main application and I want to be able to manipulate data at the back-end of my main application regarding the data received from API side. These are things like 'an action was completed/started/succeed' etc...
I understand that 'pusher' receives push notifications by JavaScript at the front-end. But I believe that there must be a way to use those notifications at the back-end as well.
If there is another way (maybe Faye? Websocket) to do that I'd love to learn what it is. Any clue would be appreciated.
Is it something doable?
Thank you
Pusher is a backend system too (to "push" updates to channels)
Endpoints
I think you may be interested in endpoints
From what I can gather, it seems you're looking to trigger the transfer of data to an endpoint once an action occurs in your API? For example:
User signs up on "API" app
API app sends "notification" to main app
Main app increases user count by 1
The way I can see this working is by either using ajax, or sending a curl request to your main app's endpoint (set in routes), triggering the action:
#main_app/config/routes.rb
post "endpoint", to: "application#endpoint"
#main_app/controllers/application_controller.rb
def endpoint
#count = Option.increment!(:user_count)
end
This will allow you to manipulate your data in the backend of your "main" app
API
The tricky, non-conventional part comes when you want to send the data from your API app to your Main app (this is where you got the "pusher" idea from)
I would personally look at sending a standard HTTP request to the Main app endpoint, probably with Curl (if from the backend):
Curl on Ruby on Rails
Rails curl syntax
You may want to install curb (CUrl RuBy) here: https://github.com/taf2/curb
I could write some code if you wanted?
I had asked the same question to the Pusher's support team and I got the exact answer I was looking for.
You can install a client library on your server
(http://pusher.com/docs/client_libraries) if there is one for your
server. You can then subscribe to a client channel this way.
In my case, I use Ruby gem which can be reached from https://github.com/pusher/pusher-ruby-client .
Hey I'm developing an iOS application which communicates with an external web service in order to make various kinds of requests.
I'm aware of Murphy's Law "Anything that can go wrong, will go wrong" and that made me think about timeouts. Currently my application does not handle the situation when a request get completed and times out simultaneously. How should I handle such situations?
Without cooperation from the service provider there's not a lot you can do. If your app sees a timeout it cannot from that deduce whether the request actually completed or not. Could be it worked and something in the infrastructure failed to deliver the response, could be that it failed and hence you saw no timely response.
You have some actions you can take that will help the user. I assume that you have available to you the details of the request you attempted to send, your app should keep that locally. You are now in a position to do some useful things:
Some service authors allow you to safely submit the same request twice. So just resubmit, if it previously worked the service will just say "yep, already done that, here's the details|, if not it will just do the work as normal.
Some service authors allow you to query the status of previous request, so you can determine what has been done and what has not.
In some cases there is no IT system way to deal with the problem, the user will need to contact a help desk or call centre. Here having the details of what was previously attempted can be very useful.
I'm trying to use the FedEx API to track packages. I can authenticate to their test server successfully (using my user credentials, account number, and meter number). However, I receive the same unhelpful response for most tracking numbers that I use in my requests; both test tracking numbers (like 999999999999) and real tracking numbers (that work well on the FedEx website) return the following:
Error Code 9040.
No information for the following shipments has been received by our system yet. Please try again or contact Customer Service at 1.800.Go.FedEx(R) 800.463.3339.
The only requests that fetch a different response are the clearly invalid ones, like "test", which returns:
Error Code 5508.
Invalid tracking number.
I tried SOAP requests using their wsdl (TrackService_v5) as well as manual non-SOAP HTTP POST requests, but their responses are exactly the same in both cases. Is something wrong on their side, or am I doing something wrong?
It seems that FedEx has disabled any test tracking numbers, in the past 999999999999 would work just fine, but now that doesn't even work. To the best of my knowledge, the only way to resolve this is to move to production. Which IMHO is bad because you have to test the tracking part of your application until you move to production.
999999999999 worked for me, but I think I am already in production environment.