Skip to content

Commit

Permalink
Add response headers to Nylas API error objects (#246)
Browse files Browse the repository at this point in the history
# Description
This PR forwards response headers from the Nylas API error response to
the serialized objects.

# License
<!-- Your PR comment must contain the following line for us to merge the
PR. -->
I confirm that this contribution is made under the terms of the MIT
license and that I have the authority necessary to make this
contribution on behalf of its copyright owner.
  • Loading branch information
mrashed-dev authored Sep 25, 2024
1 parent c9dd03c commit b5f83ef
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 4 additions & 0 deletions src/main/kotlin/com/nylas/NylasClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ class NylasClient(
errorUri = "unknown",
errorCode = "0",
statusCode = response.code(),
headers = response.headers().toMultimap(),
)
}

Expand All @@ -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
Expand All @@ -432,13 +434,15 @@ class NylasClient(

if (parsedError != null) {
parsedError.statusCode = response.code()
parsedError.headers = response.headers().toMultimap()
throw parsedError
}

throw NylasApiError(
type = "unknown",
message = "Unknown error received from the API: $responseBody",
statusCode = response.code(),
headers = response.headers().toMultimap(),
)
}

Expand Down
2 changes: 2 additions & 0 deletions src/main/kotlin/com/nylas/models/AbstractNylasApiError.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, List<String>>? = null,
) : Exception(message)
9 changes: 8 additions & 1 deletion src/main/kotlin/com/nylas/models/NylasApiError.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, List<String>>? = null,
) : AbstractNylasApiError(message, statusCode, requestId, headers)
6 changes: 5 additions & 1 deletion src/main/kotlin/com/nylas/models/NylasOAuthError.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, List<String>>? = null,
) : AbstractNylasApiError(error, statusCode, requestId, headers)
9 changes: 9 additions & 0 deletions src/test/kotlin/com/nylas/NylasClientTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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<Request>
Expand All @@ -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)
}

Expand Down Expand Up @@ -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)
}
}

Expand All @@ -254,6 +260,7 @@ class NylasClientTest {
assertEquals("unknown", exception.errorUri)
assertEquals("0", exception.errorCode)
assertEquals(500, exception.statusCode)
assertEquals(headersMultiMap, exception.headers)
}
}

Expand All @@ -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
Expand All @@ -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
Expand Down

0 comments on commit b5f83ef

Please sign in to comment.