Skip to content
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

Error Handling #27

Closed
danpaquin opened this issue May 12, 2017 · 9 comments
Closed

Error Handling #27

danpaquin opened this issue May 12, 2017 · 9 comments

Comments

@danpaquin
Copy link
Owner

Error Handling is very poor with this project. Does anyone have insight on how they have their scripts to work around errors? It will allow me to integrate an error check and return for all calls that works well into the workflows of everyone.

@bryankaplan
Copy link
Contributor

@danpaquin I'm glad you raised this issue, as it's indeed one of the main things that we can improve.

One simple approach would be to define a single generic API exception, something like:

class GdaxApiError(Exception):
    pass

And then use it like:

response = requests.get(...).json()
if response.get('type') == 'error':
    raise GdaxApiError(response.get('message'))
return response

@sonph
Copy link

sonph commented Jul 21, 2017

I'd extend on @bryankaplan's comment to suggest that we define a exceptions.py file that houses more meaningful exception types, for example InvalidProductId, ConnectionError or InvalidApiKey.

This way we can look at the response from gdax (or catch an exception from requests), inspect the message/status code, raise an exception accordingly and let the client handle the exception.

We can also write a decorator that analyzes the json response and either raise an error, or pass the successful result through.

import exceptions

def check_result(fun, ...):
  status, result = fun(args, kwargs)
  if status == 401:
    raise exceptions.InvalidApiKey(result['message'])
  if status == 500:
    raise exceptions.GdaxInternalServerError(result['message'])

@check_result
def buy(self, ...):
   ...
  return r.status_code, results

And clients can catch our exceptions like:

def short(...):
  try:
    ...
  except gdax.exceptions.GdaxInternalServerError:
    logging.warn('gdax craps out again')

@dahifi
Copy link

dahifi commented Oct 29, 2017

There certainly needs to be some kind of error checking for a dropped connection. My program uses the WebsocketClient and after a few hours I come back to the display telling me 'socket is already closed'. I'm going to capture output to see if I can figure out whats happening, but it seems that we need to add some sort of try/catch WebSocketConnectionClosedException that can automatically reconnect the session. I'm not quite sure where I would put that yet but I'm investigating.

@ericbhanson
Copy link

This could be more specific, but I added this to my script to handle 'rate limit exceeded' messages and other API errors, which are returned as dictionaries instead of lists:

if (type(candlesticks) is dict):
                logging.error('Returned API error - retrying in 5 seconds...')
                time.sleep(5)

@ericbhanson
Copy link

This might be more of a preventative feature than an error-handling feature, but would it make sense to include rounding of numbers that have too many significant digits for the API to handle? I've gotten an error in response a few times when I haven't (for example) rounded a sale order properly and it would be great if the wrapper could handle that automatically. GDAX doesn't document how many digits after the decimal point they allow, but from the UI I'm guessing it's 8.

@mcardillo55 mcardillo55 mentioned this issue Dec 11, 2017
@desai827
Copy link

desai827 commented Jan 2, 2018

@ericbhanson GDAX supports up to 8 for coin size and 2 for price. I agree that it'd be helpful if it was automatically handled. In the mean time, here's what I'm using - it rounds down so we don't end up in a situation where rounding up would mean the funds/coins are unavailable.

def roundDown(n, d=2):
	d = int('1' + ('0' * d))
	return floor(float(n)*d)/d

I then call roundDown(float((usd * 0.997) / price), 8) to determine the coin amount. The 0.997 allows me to ensure I have enough to cover any fees.

@smacbeth
Copy link

@desai827 where did you get the information that GDAX supports 8 significant digits for coin size and 2 for the price? When I make a market order say .01 coins, the fee appears to be computed to 8 significant digits, as does the cost. So it appears as if they are managing the account balance and trade execution at 8 significant digits as well.

@desai827
Copy link

@smacbeth I didn't find the information in any particular place. Rather, I found when trying to enter a price that utilizes more than 2 digits after the decimal, I'd receive an error. Similarly, when entering a coin size greater than 8 digits after the decimal, I'd receive an error.

@danpaquin
Copy link
Owner Author

This thread is becoming off topic. Please follow #260 for updates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants