Skip to content

Added OAuthException and Tests, fixes #287 #289

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/main/kotlin/com/workos/WorkOS.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import com.github.kittinunf.fuel.core.Request
import com.github.kittinunf.fuel.core.Response
import com.workos.auditlogs.AuditLogsApi
import com.workos.common.exceptions.BadRequestException
import com.workos.common.exceptions.OAuthException
import com.workos.common.exceptions.GenericServerException
import com.workos.common.exceptions.NotFoundException
import com.workos.common.exceptions.UnauthorizedException
import com.workos.common.exceptions.UnprocessableEntityException
import com.workos.common.http.BadRequestExceptionResponse
import com.workos.common.http.OAuthErrorResponse
import com.workos.common.http.GenericErrorResponse
import com.workos.common.http.RequestConfig
import com.workos.common.http.UnprocessableEntityExceptionResponse
Expand Down Expand Up @@ -363,8 +365,15 @@ class WorkOS(

when (val status = response.statusCode) {
400 -> {
val responseData = mapper.readValue(payload, BadRequestExceptionResponse::class.java)
throw BadRequestException(responseData.message, responseData.code, responseData.errors, requestId)
// Try to parse as OAuth error first
val isOAuthError = payload.contains("\"error\"") && payload.contains("\"error_description\"")
if (isOAuthError) {
val oauthError = mapper.readValue(payload, OAuthErrorResponse::class.java)
throw OAuthException(oauthError.error, oauthError.error_description, requestId)
} else {
val responseData = mapper.readValue(payload, BadRequestExceptionResponse::class.java)
throw BadRequestException(responseData.message, responseData.code, responseData.errors, requestId)
}
}

401 -> {
Expand Down
14 changes: 14 additions & 0 deletions src/main/kotlin/com/workos/common/exceptions/OAuthException.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.workos.common.exceptions

/**
* Thrown when the API returns an OAuth error (e.g., invalid_grant).
*
* @param error The OAuth error code.
* @param errorDescription The OAuth error description.
* @param requestId The ID of the correlating request specified in the 'X-Request-ID' header.
*/
class OAuthException(
val error: String?,
val errorDescription: String?,
val requestId: String
) : Exception(errorDescription)
6 changes: 6 additions & 0 deletions src/main/kotlin/com/workos/common/http/OAuthErrorResponse.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.workos.common.http

data class OAuthErrorResponse(
val error: String?,
val error_description: String?
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

package com.workos.test.user_management


import com.workos.common.exceptions.OAuthException
import com.workos.test.TestBase
import org.junit.jupiter.api.Assertions.assertThrows
import kotlin.test.Test

class OAuthErrorHandlingTest : TestBase() {
val workos = createWorkOSClient()

@Test
fun authenticateWithCodeShouldThrowOAuthExceptionOnInvalidGrant() {
stubResponse(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Consider adding indentation consistency - the stubResponse call has unusual indentation that doesn't match the rest of the codebase

"/user_management/authenticate",
"""
{
"error" : "invalid_grant",
"error_description" : "The code 'D01K0EWQ9V6SYP9F5D14QPHBQ8Edd' has expired or is invalid."
}
""",
responseStatus = 400,
requestBody = """{
"client_id": "client_id",
"client_secret": "apiKey",
"grant_type": "authorization_code",
"code": "invalid_code"
}"""
)

assertThrows(OAuthException::class.java) {
workos.userManagement.authenticateWithCode(
"client_id",
"invalid_code"
)
}
}
}
Loading