From a8e2e33b91fc84515e9d55be658fc8f0d995b01c Mon Sep 17 00:00:00 2001 From: Mostafa Rashed <17770919+mrashed-dev@users.noreply.github.com> Date: Wed, 25 Sep 2024 12:57:58 -0400 Subject: [PATCH 1/5] Add a headers field for Nylas API errs --- .../kotlin/com/nylas/models/AbstractNylasApiError.kt | 2 ++ src/main/kotlin/com/nylas/models/NylasApiError.kt | 9 ++++++++- src/main/kotlin/com/nylas/models/NylasOAuthError.kt | 6 +++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/nylas/models/AbstractNylasApiError.kt b/src/main/kotlin/com/nylas/models/AbstractNylasApiError.kt index c6f145f4..eedf176a 100644 --- a/src/main/kotlin/com/nylas/models/AbstractNylasApiError.kt +++ b/src/main/kotlin/com/nylas/models/AbstractNylasApiError.kt @@ -5,9 +5,11 @@ package com.nylas.models * @param message The error message. * @param statusCode The HTTP status code of the error response. * @param requestId The unique identifier of the request. + * @param headers The HTTP headers of the error response. */ sealed class AbstractNylasApiError( override val message: String, open var statusCode: Int? = null, open var requestId: String? = null, + open var headers: Map>? = null, ) : Exception(message) diff --git a/src/main/kotlin/com/nylas/models/NylasApiError.kt b/src/main/kotlin/com/nylas/models/NylasApiError.kt index f634218f..fd38faaa 100644 --- a/src/main/kotlin/com/nylas/models/NylasApiError.kt +++ b/src/main/kotlin/com/nylas/models/NylasApiError.kt @@ -25,5 +25,12 @@ data class NylasApiError( * The HTTP status code of the error response */ override var statusCode: Int? = null, + /** + * The HTTP status code of the error response. + */ override var requestId: String? = null, -) : AbstractNylasApiError(message, statusCode, requestId) + /** + * The HTTP headers of the error response + */ + override var headers: Map>? = null, +) : AbstractNylasApiError(message, statusCode, requestId, headers) diff --git a/src/main/kotlin/com/nylas/models/NylasOAuthError.kt b/src/main/kotlin/com/nylas/models/NylasOAuthError.kt index 6e5dd330..e467f332 100644 --- a/src/main/kotlin/com/nylas/models/NylasOAuthError.kt +++ b/src/main/kotlin/com/nylas/models/NylasOAuthError.kt @@ -35,4 +35,8 @@ data class NylasOAuthError( * The HTTP status code of the error response. */ override var statusCode: Int? = null, -) : AbstractNylasApiError(error, statusCode, requestId) + /** + * The HTTP headers of the error response + */ + override var headers: Map>? = null, +) : AbstractNylasApiError(error, statusCode, requestId, headers) From 780f151e34a1070e7231ff6dcd78279c0e987e9d Mon Sep 17 00:00:00 2001 From: Mostafa Rashed <17770919+mrashed-dev@users.noreply.github.com> Date: Wed, 25 Sep 2024 12:59:22 -0400 Subject: [PATCH 2/5] forward response headers to err object --- src/main/kotlin/com/nylas/NylasClient.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/kotlin/com/nylas/NylasClient.kt b/src/main/kotlin/com/nylas/NylasClient.kt index e30bc67c..186c4c9d 100644 --- a/src/main/kotlin/com/nylas/NylasClient.kt +++ b/src/main/kotlin/com/nylas/NylasClient.kt @@ -402,6 +402,7 @@ class NylasClient( errorUri = "unknown", errorCode = "0", statusCode = response.code(), + headers = response.headers().toMultimap(), ) } @@ -423,6 +424,7 @@ class NylasClient( type = "unknown", message = "Unknown error received from the API: $responseBody", statusCode = response.code(), + headers = response.headers().toMultimap(), ) } else -> throw ex @@ -439,6 +441,7 @@ class NylasClient( type = "unknown", message = "Unknown error received from the API: $responseBody", statusCode = response.code(), + headers = response.headers().toMultimap(), ) } From 14885ac1969fc6d54de97cd8e2b9a591b4b19c97 Mon Sep 17 00:00:00 2001 From: Mostafa Rashed <17770919+mrashed-dev@users.noreply.github.com> Date: Wed, 25 Sep 2024 12:59:53 -0400 Subject: [PATCH 3/5] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a3f9ea1..5dcc409a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Added * Added new error class `NylasSdkRemoteClosedError` for when the remote connection is closed * Added support for new filter fields for listing events +* Added response headers to Nylas API error objects ### [2.4.1] - Released 2024-07-26 From 51b09c138c20e22e915feb0bda0801829f61087f Mon Sep 17 00:00:00 2001 From: Mostafa Rashed <17770919+mrashed-dev@users.noreply.github.com> Date: Wed, 25 Sep 2024 14:42:10 -0400 Subject: [PATCH 4/5] set headers in all cases --- src/main/kotlin/com/nylas/NylasClient.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/kotlin/com/nylas/NylasClient.kt b/src/main/kotlin/com/nylas/NylasClient.kt index 186c4c9d..b85f7021 100644 --- a/src/main/kotlin/com/nylas/NylasClient.kt +++ b/src/main/kotlin/com/nylas/NylasClient.kt @@ -434,6 +434,7 @@ class NylasClient( if (parsedError != null) { parsedError.statusCode = response.code() + parsedError.headers = response.headers().toMultimap() throw parsedError } From 7c2d6206b276d314d9a7b10be47b82960d9d8f12 Mon Sep 17 00:00:00 2001 From: Mostafa Rashed <17770919+mrashed-dev@users.noreply.github.com> Date: Wed, 25 Sep 2024 14:42:18 -0400 Subject: [PATCH 5/5] update tests --- src/test/kotlin/com/nylas/NylasClientTest.kt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/test/kotlin/com/nylas/NylasClientTest.kt b/src/test/kotlin/com/nylas/NylasClientTest.kt index b87d0637..d85b358e 100644 --- a/src/test/kotlin/com/nylas/NylasClientTest.kt +++ b/src/test/kotlin/com/nylas/NylasClientTest.kt @@ -182,6 +182,8 @@ class NylasClientTest { private val mockCall: Call = mock(Call::class.java) private val mockResponse: Response = mock(Response::class.java) private val mockResponseBody: ResponseBody = mock(ResponseBody::class.java) + private val mockHeaderResponse: Headers = mock(Headers::class.java) + private val headersMultiMap = mapOf("header1" to listOf("value1"), "header2" to listOf("value2")) @Captor private lateinit var requestCaptor: ArgumentCaptor @@ -196,6 +198,8 @@ class NylasClientTest { whenever(mockCall.execute()).thenReturn(mockResponse) whenever(mockResponse.isSuccessful).thenReturn(true) whenever(mockResponse.body()).thenReturn(mockResponseBody) + whenever(mockResponse.headers()).thenReturn(mockHeaderResponse) + whenever(mockHeaderResponse.toMultimap()).thenReturn(headersMultiMap) nylasClient = NylasClient("testApiKey", mockOkHttpClientBuilder) } @@ -232,6 +236,8 @@ class NylasClientTest { assertEquals("https://accounts.nylas.io/#tag/Event-Codes", exception.errorUri) assertEquals("500", exception.errorCode) assertEquals(401, exception.statusCode) + assertEquals("eccc9c3f-7150-48e1-965e-4f89714ab51a", exception.requestId) + assertEquals(headersMultiMap, exception.headers) } } @@ -254,6 +260,7 @@ class NylasClientTest { assertEquals("unknown", exception.errorUri) assertEquals("0", exception.errorCode) assertEquals(500, exception.statusCode) + assertEquals(headersMultiMap, exception.headers) } } @@ -273,6 +280,7 @@ class NylasClientTest { assertEquals("Request had invalid authentication credentials.", exception.providerError?.get("error")) assertEquals("4c2740b4-52a4-412e-bdee-49a6c6671b22", exception.requestId) assertEquals(400, exception.statusCode) + assertEquals(headersMultiMap, exception.headers) } @Test @@ -289,6 +297,7 @@ class NylasClientTest { assertEquals("unknown", exception.type) assertEquals("Unknown error received from the API: not a json", exception.message) assertEquals(400, exception.statusCode) + assertEquals(headersMultiMap, exception.headers) } @Test