degiro-connector: Is there a way to access fault data on API requests, instead of returning `None`?
For example the Trading API might return a negative response while creating or updating orders, see for example the error response in https://github.com/Chavithra/degiro-connector/pull/50#issuecomment-997392518
{"errors": [{"text": "Le prix renseigné (300.0500) ne respecte pas la tick size (écart minimal entre les décimales). Le prix doit être un multiple de (0.1000)."}]}
However, this is only observed in the CRITICAL Logging.
The functions check_order(), confirm_order() and update_order() will return just None in case of an error.
It’s important to know what the cause of the error is. Is it for example an error with the order (such as the example above), which is refused by DeGiro? Or is it caused by a server error (HTTP Status codes) or even no internet connection (HTTP Connection error)?
This data seems already present in the underlying code of the Connector, as can be seen in the Logging messages. Would it be possible to use this in the response of the functions?
For example the standard output of these functions can be a dict with 3 parameters. Here the response of a successful request:
{
"http_status" : 200
"result" : True
"error" : None
}
where result can also contain a dict, for example with the current response from check_order()
In case of a DeGiro error, it will look like:
{
"http_status" : 200
"result" : False
"error" : 'Le prix renseigné (300.0500) ne respecte pas la tick size (écart minimal entre les décimales). Le prix doit être un multiple de (0.1000).'
}
In case of a Network error, it will look like:
{
"http_status" : 500
"result" : False
"error" : 'The server has an internal error.'
}
This information is useful for our script, to decide what fault action to take. E.g.
- updating an order
- a retry
- an abort (“call the manager” 😃)
Please let me know if this is possible.
About this issue
- Original URL
- State: open
- Created 3 years ago
- Comments: 27 (25 by maintainers)
Commits related to this issue
- Fix for issue #54 * Corrected Pythonian names * Added missing `free_space_new` — committed to funnel20/degiro-connector by funnel20 2 years ago
- Fix for issue Chavithra#54 * Corrected Pythonian names — committed to funnel20/degiro-connector by funnel20 2 years ago
- Fix for issue Chavithra#54 Removed duplicate `free_space_new` — committed to funnel20/degiro-connector by funnel20 2 years ago
My bad, will respect the process.
That’s a great work @funnel20 ! Will check that in detail the following days and give you my feedback.
I’ve been prototyping today and discovered that the exceptions that are raised by the
requestslibrary already have therequestandresponseobjects as can be seen in the source code of theRequestException. All other exceptions, such asHTTPError,ConnectTimeout,ConnectionErrorandJSONDecodeError, inherit fromRequestException. So no need for custom exception(s) 👍Proposed changes
Based on the existing code of version 2.0.14 (for example for
update_order()) I made a generic request handler for fictitious callget_dataof classAPI:Notes
raise_exceptionthat defaults toFalsefor a seamless migration of existing users.raw.HTTPError(to print details to terminal) and the genericException.These 2 exceptions are handled generically in method
handle_exception():raise_exceptionisFalse. The only new feature is the Tip in the terminal about this new input parameter.raise_exceptionisTrue, is as simple as forwarding the existing exception.Notes
ExceptionUtils.get_full_class_name(). It will return a string like “requests.exceptions.ConnectTimeout”. The source code can be found in the executable example at the bottom of this post.Existing usage
Existing users will still use the function call without argument:
This will either:
Truefor HTTP 200Noneand show logs in the terminal in case of an error. For example forHTTPError:New usage
Add parameter
raise_exceptionto the function call and set it toTrue. Embed the call in atry/exceptcondition and handle whatever specific or generic exceptions:This will either:
Truefor HTTP 200Noneand show the same logs as the existing code (except the tip) in the terminal in case of an error. For example forHTTPError, the first 2 log lines come from the API. The other 2 demonstrate the existence of therequestandresponseobjects in the returned exception:Notes
HTTPErrordetails contains a reference toExceptionUtils.http_status_code(). It’s a convenient method to return the HTTP Status Code as integer (e.g.404). The source code can be found in the executable example at the bottom of this post. Of course this is also possible byexception.response.status_code, but that might raise aAttributeErrorin case the exception has noresponseattribute.Working example code
Here is the code for a working example. It shows the current output in the Terminal, and the new output when using
raise_exception. Just copy/paste everything in a fileerror-handling.pyand run. Note that the comments inget_data()contain instructions to force different exceptions.@Chavithra Please let me know what you think about this.
Exceptionto handle our dedicated set of return parameters. But when for example aConnectionExceptionoccurs (e.g. no internet connection), there is no http response. So we can either populate that return parameter asNone, but then the exception parser still has no idea about the root cause and what kind of action should take place. So probably it’s better to return a dedicated custom Exception for each possible Exception that the API connection and parsing can raise.Hello @funnel20, alright will try to formulate a specification tonight (or during the week if I can’t tonight).