stripity-stripe icon indicating copy to clipboard operation
stripity-stripe copied to clipboard

An exception is thrown rather than a result with {:error, ...} being returned

Open GildedHonour opened this issue 7 years ago • 26 comments

This code throws an unhandled exception instead of returning a result with {:error, res} :

  # 1
  res = Stripe.Customers.create(email: stripe_email, source: stripe_token)
  IO.puts("ok or error")

  # or 2
  case Stripe.Customers.create(email: stripe_email, source: stripe_token) do
    {:ok, data} ->  IO.puts("ok")
    {:error, data} ->  IO.puts("error")
  end

Exception being:

  ** (MatchError) no match of right hand side value: {:error, %HTTPoison.Error{id: nil, reason: :nxdomain}}  

It's cased by "Stripe.Customers.create(...)" and unhandled and thus IO.puts(...) won't execute.

Bug?

GildedHonour avatar Aug 14 '17 05:08 GildedHonour

@GildedHonour We're going to need more information here.

  • What's the exact exception you're getting?
  • What are the values of stripe_email and stripe_token (in case those are not safe to share, what are their formats, etc.)

I'm performing the calls you listed above and cannot reproduce the issue with my data.

begedin avatar Aug 14 '17 06:08 begedin

  1. the exception has been specified
  2. they're in the proper format

try stripe card number: 4000000000000341

GildedHonour avatar Aug 14 '17 06:08 GildedHonour

@begedin

GildedHonour avatar Aug 16 '17 18:08 GildedHonour

@begedin sorry to double-ping, but I haven't had a chance to try with this Stripe test card number. I'm not sure which card reason it refers to, but you should be able to find it on their testing page.

joshsmith avatar Aug 17 '17 05:08 joshsmith

@GildedHonour

I was unable to produce your result with the data you provided. However, I did look into the error you are getting and it's generally caused when you're attempting to hit a URL that does not exist. Basically, it means "non-existant domain".

Considering that, I tried to put a non-existant url into my environment's :stripity_stripe, :api_base_url "field" and when I did that:

Application.put_env(:stripity_stripe, :api_base_url, "https://api2.stripe.com/v22/") # this url does not exist

I got your exact error:

Stripe.Customers.create(email: "[email protected]", source: "4000000000000341")

** (MatchError) no match of right hand side value: {:error, %HTTPoison.Error{id: nil, reason: :nxdomain}}
    (stripity_stripe) lib/stripe.ex:107: Stripe.make_request_with_key/6
    (stripity_stripe) lib/stripe/customers.ex:58: Stripe.Customers.create/2

We could argue that this poison exception needs to be handled by our library and it might be worth it to continue that conversation here, or in a separate issue, but for now, could you double check what the value of Application.get_env(:stripity_stripe, :api_base_url) is on your machine and double check it?

Note that if it was left blank, it would default to "https://api.stripe.com/v1/", so it must have been altered.

Also note that this could also be a network configuration problem

http://erlang.org/pipermail/erlang-questions/2010-March/050349.html

begedin avatar Aug 17 '17 07:08 begedin

it works well with a correct, test card number.

GildedHonour avatar Aug 17 '17 08:08 GildedHonour

i'll double check.

GildedHonour avatar Aug 17 '17 08:08 GildedHonour

The problem is that you get MatchError exception here https://github.com/code-corps/stripity_stripe/blob/master/lib/stripe.ex#L107 in a case of network problems and users can not properly handle this situation by their application. So simple solution may be something like this:

case request(method, endpoint, rb, rh, options) do
  {:ok, response} -> response.body
  {:error, error} -> {:error, error}
end

not sure maybe there is better solution

anronin avatar Aug 17 '17 08:08 anronin

for whom? for me, as a client, stripity_stripe doesn't provide the public method "request" from its api.

GildedHonour avatar Aug 17 '17 08:08 GildedHonour

i mean, we need changes to the make_request_with_key function in stripity_stripe

anronin avatar Aug 17 '17 08:08 anronin

@anronin I agree we probably need to fix that, but I'm trying to help @GildedHonour avoid having to wait for a fix.

The reality is, even though that place in the code is a failure point, I'm still not getting the error @GildedHonour getting when making the same call, so I want to find out why. The only way I was able to get that error was by setting a bad api url.

Online resources also say that it can happen with an incorrect network configuration.

If we fix the failure point, @GildedHonour will still be getting errors, it's just that MatchError won't be raised.

begedin avatar Aug 17 '17 08:08 begedin

@anronin That being said, we clearly have a bug, so I'll tag it as such, so it can be fixed by whoever gets the chance.

begedin avatar Aug 17 '17 08:08 begedin

Sorry, misunderstood this issue and now i get it and i also think that this reason:: nxdomain is caused by network error or incorrect configuration

anronin avatar Aug 17 '17 08:08 anronin

I have had this happen twice in production as well, both on the Stripe.Subscriptions.create method - with dire consequences, since the charge actually happened, but my logic to upgrade the account and attach payment information would not happen since the exception would stop the whole process.

arvidkahl avatar Sep 03 '17 19:09 arvidkahl

@arvidkahl do you have any extra output that you can provide? Is this also an nxdomain error?

Per @begedin's comment above:

If we fix the failure point, @GildedHonour will still be getting errors, it's just that MatchError won't be raised.

Is it preferable that you have an error of some sort at least that is handleable? I think this is what @begedin was saying. We could at least make it so you can recover from it somehow.

Bear in mind that there are some serious refactorings happening, but I would obviously love to get you out of errors happening in production.

joshsmith avatar Sep 04 '17 16:09 joshsmith

It was a HTTPoison Timeout,

14:58:06.815 [error] #PID<0.217.4> running ModuleName.Endpoint terminated 
Server: app.REDACTED.com:80 (http) 
Request: POST /api/REDACTED/subscribe 
** (exit) an exception was raised: 
** (MatchError) no match of right hand side value: {:error, %HTTPoison.Error{id: nil, reason: :timeout}} 
          (stripity_stripe) lib/stripe.ex:62: Stripe.make_request_with_key/6 

arvidkahl avatar Sep 04 '17 17:09 arvidkahl

I've stumbled into the same issue as @arvidkahl - a customer makes a payment, but the request process crashes due to an HTTPoison timeout, which means that my application is unable to handle the payment.

2017-09-15 17:03:59.702 [error] GenServer #PID<0.10226.14> terminating
** (MatchError) no match of right hand side value: {:error, %HTTPoison.Error{id: nil, reason: :timeout}}
    (stripity_stripe) lib/stripe.ex:107: Stripe.make_request_with_key/6
    (stripity_stripe) lib/stripe/charges.ex:67: Stripe.Charges.create/3
...

I haven't been able to figure out what caused these timeouts in the first place (I've observed this particular issue 3 times so far)

lcjtrifork avatar Sep 18 '17 08:09 lcjtrifork

What infrastructure are you running this on? Some sort of PaaS?

joshsmith avatar Sep 18 '17 19:09 joshsmith

I'm running this on an AWS EC2 instance.

lcjtrifork avatar Sep 21 '17 08:09 lcjtrifork

I am running it on a container-as-a-service platform called Sloppy.io, where the containers are behind haproxy reverse proxies with a global 15sec hard connection timeout.

arvidkahl avatar Sep 21 '17 09:09 arvidkahl

Ah well for @arvidkahl I think I might understand. If it were Heroku or something there also might be something happening with a request timeout. If the operation is sufficiently large and run alongside some other op you're doing, then a timeout may well occur as the connection to your client closes. This is pure speculation, though.

Given all the rework that's coming I'm just trying to hold off too much since the entire request/response stack is being rewritten.

joshsmith avatar Sep 25 '17 17:09 joshsmith

FWIW, hackney errors are handled correctly in the rewrite of the 2.0 stack. I don't think 1.x will be updated to fix this (the fact that it's HTTPoison not hackney makes me think it's happening in 1.x).

mjadczak avatar Sep 25 '17 20:09 mjadczak

Just happen to me today (timeout), I think the stripe API was having some issues. I will be migrating to 2.0.0 (was using 1.6.0).

speeddragon avatar Jan 09 '18 14:01 speeddragon

@speeddragon please let me know if you have any issues at all with 2.0. I'm running it in production but am happy to help diagnose and fix any problems.

joshsmith avatar Jan 10 '18 18:01 joshsmith

@lcjtrifork @joshsmith This happened to me today N times the user tried to make a payment. I'm using version 2.0 and it's very unlikely that Stripe response time was so slow (5 seconds Poison default) between 10-20 minutes attempts from the user. Also, the Stripe.Customer.create returned {:error, timeout...} but the Stripe successfully created the Customer on their side.

What could be another reason to that happened?

luccasmaso avatar Mar 28 '18 19:03 luccasmaso

To be honest, I sometimes think it IS the stripe API, or at least parts of it. I have no means to trace the timeout or its origins, so all I can do is guess. The {:error, timeout} happens particularly often when updating a customer (or rather when they update their CC info). So I would assume that POST/PUT operations have some unforeseeable timeout on occasion. (This is still 1.x, I have yet to upgrade to 2.x)

arvidkahl avatar Mar 29 '18 05:03 arvidkahl

This issue has been automatically marked as "stale:discard". If this issue still relevant, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment.

github-actions[bot] avatar Nov 11 '23 02:11 github-actions[bot]

Closing this issue after a prolonged period of inactivity. If this issue is still relevant, feel free to re-open the issue. Thank you!

github-actions[bot] avatar Nov 27 '23 02:11 github-actions[bot]