From c01aaf12e848491fb027f7a949482a5095fab555 Mon Sep 17 00:00:00 2001 From: bchavez Date: Fri, 30 Nov 2018 17:38:07 -0800 Subject: [PATCH] Add GetErrorMessageAsync() extensions for exception error handling. --- HISTORY.md | 3 +++ README.md | 16 ++++++++++++ Source/Coinbase.Pro/CoinbaseProClient.cs | 26 +++++++++++++++++++ .../IntegrationTests/GeneralTests.cs | 18 +++++++++++++ 4 files changed, 63 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index 7131c40..6d73637 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,6 @@ +## v2.0.2 +* Added GetErrorMessageAsync() extension method. + ## v2.0.1 * Production ready. Models and APIs finalized. diff --git a/README.md b/README.md index f056b9b..b04ee44 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,22 @@ The `order` object returned by the trading engine will have similar values to th * [`CoinbaseProWebSocket`](https://docs.pro.coinbase.com/?r=1#websocket-feed) - [Examples](https://github.com/bchavez/Coinbase.Pro/blob/master/Source/Coinbase.Tests/IntegrationTests/WebSocketTests.cs) +### Error Handling +When errors occur after calling an API, **Coinbase Pro** delivers error messages in the response body of an failed HTTP call. To get the error message of a failed API call, first wrap your call in a `try/catch` statement and handle the `Exception ex`. The `GetErrorMessageAsync()` extension method will read the response body of the failed HTTP call as shown below: +```csharp +try +{ + var order = await client.Orders.PlaceLimitOrderAsync( + OrderSide.Buy, "BTCX-USDX", size: 1, limitPrice: 5000m); +} +catch (Exception ex) +{ + var errorMsg = await ex.GetErrorMessageAsync(); + Console.WriteLine(errorMsg); +} +//OUTPUT: "Product not found" +``` + ### Pagination Some **Coinbase Pro** APIs are [paginable](https://docs.pro.coinbase.com/?r=1#pagination). However, **Coinbase Pro**'s paging can be [a little confusing](https://docs.pro.coinbase.com/?r=1#pagination) at first. So, let's review. Consider the following diagram below that illustrates the `Current Point In Time` over a paginable set of data with an item size of 5 items per page: ``` diff --git a/Source/Coinbase.Pro/CoinbaseProClient.cs b/Source/Coinbase.Pro/CoinbaseProClient.cs index 9015cdb..bf91cb1 100644 --- a/Source/Coinbase.Pro/CoinbaseProClient.cs +++ b/Source/Coinbase.Pro/CoinbaseProClient.cs @@ -1,6 +1,8 @@ using System; using System.Globalization; +using System.Threading; using System.Threading.Tasks; +using Coinbase.Pro.Models; using Flurl.Http; using Flurl.Http.Configuration; @@ -93,4 +95,28 @@ async Task SetHeaders(HttpCall http) settings.BeforeCallAsync = SetHeaders; } } + + public static class ExtensionsForExceptions + { + /// + /// Parses the response body of the failed HTTP call return any error status messages. + /// + public static async Task GetErrorMessageAsync(this FlurlHttpException ex) + { + if( ex is null ) return null; + + var error = await ex.GetResponseJsonAsync() + .ConfigureAwait(false); + + return error?.Message; + } + + /// + /// Parses the response body of the failed HTTP call return any error status messages. + /// + public static Task GetErrorMessageAsync(this Exception ex) + { + return GetErrorMessageAsync(ex as FlurlHttpException); + } + } } diff --git a/Source/Coinbase.Tests/IntegrationTests/GeneralTests.cs b/Source/Coinbase.Tests/IntegrationTests/GeneralTests.cs index d4cc4c2..e174034 100644 --- a/Source/Coinbase.Tests/IntegrationTests/GeneralTests.cs +++ b/Source/Coinbase.Tests/IntegrationTests/GeneralTests.cs @@ -93,6 +93,24 @@ public async Task create_order4() o.Dump(); } + [Test] + public async Task create_order5_with_error() + { + try + { + var o = await this.client.Orders.PlaceLimitOrderAsync( + OrderSide.Buy, "BTCX-USD", size: 1, limitPrice: 5000m); + + //o.Dump(); + } + catch (Exception ex) + { + var errorMsg = await ex.GetErrorMessageAsync(); + errorMsg.Dump(); + } + + } + [Test] public async Task get_fills1() {