Skip to content

Commit

Permalink
added quota exceeded exception (#93)
Browse files Browse the repository at this point in the history
Co-authored-by: David Motsonashvili <[email protected]>
Co-authored-by: Rodrigo Lazo <[email protected]>
  • Loading branch information
3 people authored Mar 25, 2024
1 parent 672f0a4 commit 47135cf
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,9 @@ private suspend fun validateResponse(response: HttpResponse) {
if (message == "User location is not supported for the API use.") {
throw UnsupportedUserLocationException()
}
if (message.contains("quota")) {
throw QuotaExceededException(message)
}
throw ServerException(message)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ sealed class GoogleGenerativeAIException(message: String, cause: Throwable? = nu
is kotlinx.serialization.SerializationException ->
SerializationException(
"Something went wrong while trying to deserialize a response from the server.",
cause
cause,
)
is TimeoutCancellationException ->
RequestTimeoutException("The request failed to complete in the allotted time.")
Expand Down Expand Up @@ -68,7 +68,7 @@ class InvalidAPIKeyException(message: String, cause: Throwable? = null) :
class PromptBlockedException(val response: GenerateContentResponse, cause: Throwable? = null) :
GoogleGenerativeAIException(
"Prompt was blocked: ${response.promptFeedback?.blockReason?.name}",
cause
cause,
)

/**
Expand Down Expand Up @@ -97,7 +97,7 @@ class InvalidStateException(message: String, cause: Throwable? = null) :
class ResponseStoppedException(val response: GenerateContentResponse, cause: Throwable? = null) :
GoogleGenerativeAIException(
"Content generation stopped. Reason: ${response.candidates?.first()?.finishReason?.name}",
cause
cause,
)

/**
Expand All @@ -108,6 +108,10 @@ class ResponseStoppedException(val response: GenerateContentResponse, cause: Thr
class RequestTimeoutException(message: String, cause: Throwable? = null) :
GoogleGenerativeAIException(message, cause)

/** The quota for this API key is depleted, retry this request at a later time. */
class QuotaExceededException(message: String, cause: Throwable? = null) :
GoogleGenerativeAIException(message, cause)

/** Catch all case for exceptions not explicitly expected. */
class UnknownException(message: String, cause: Throwable? = null) :
GoogleGenerativeAIException(message, cause)
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,16 @@ internal class UnarySnapshotTests {
}
}

@Test
fun `quota exceeded`() =
goldenUnaryFile("failure-quota-exceeded.json", HttpStatusCode.BadRequest) {
withTimeout(testTimeout) {
shouldThrow<QuotaExceededException> {
apiController.generateContent(textGenerateContentRequest("prompt"))
}
}
}

@Test
fun `image rejected`() =
goldenUnaryFile("failure-image-rejected.json", HttpStatusCode.BadRequest) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"error": {
"code": 429,
"message": "Quota exceeded for quota metric 'Generate Content API requests per minute' and limit 'GenerateContent request limit per minute for a region' of service 'generativelanguage.googleapis.com' for consumer 'project_number:348715329010'.",
"status": "RESOURCE_EXHAUSTED",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "RATE_LIMIT_EXCEEDED",
"domain": "googleapis.com",
"metadata": {
"service": "generativelanguage.googleapis.com",
"consumer": "projects/348715329010",
"quota_limit_value": "0",
"quota_limit": "GenerateContentRequestsPerMinutePerProjectPerRegion",
"quota_location": "us-east2",
"quota_metric": "generativelanguage.googleapis.com/generate_content_requests"
}
},
{
"@type": "type.googleapis.com/google.rpc.Help",
"links": [
{
"description": "Request a higher quota limit.",
"url": "https://cloud.google.com/docs/quota#requesting_higher_quota"
}
]
}
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@ sealed class GoogleGenerativeAIException(message: String, cause: Throwable? = nu
is com.google.ai.client.generativeai.common.ServerException ->
ServerException(cause.message ?: "", cause.cause)
is com.google.ai.client.generativeai.common.InvalidAPIKeyException ->
InvalidAPIKeyException(
cause.message ?: "",
)
InvalidAPIKeyException(cause.message ?: "")
is com.google.ai.client.generativeai.common.PromptBlockedException ->
PromptBlockedException(cause.response.toPublic(), cause.cause)
is com.google.ai.client.generativeai.common.UnsupportedUserLocationException ->
Expand All @@ -57,6 +55,8 @@ sealed class GoogleGenerativeAIException(message: String, cause: Throwable? = nu
RequestTimeoutException(cause.message ?: "", cause.cause)
is com.google.ai.client.generativeai.common.UnknownException ->
UnknownException(cause.message ?: "", cause.cause)
is com.google.ai.client.generativeai.common.QuotaExceededException ->
QuotaExceededException(cause.message ?: "", cause.cause)
else -> UnknownException(cause.message ?: "", cause)
}
is TimeoutCancellationException ->
Expand Down Expand Up @@ -89,7 +89,7 @@ class InvalidAPIKeyException(message: String, cause: Throwable? = null) :
class PromptBlockedException(val response: GenerateContentResponse, cause: Throwable? = null) :
GoogleGenerativeAIException(
"Prompt was blocked: ${response.promptFeedback?.blockReason?.name}",
cause
cause,
)

/**
Expand Down Expand Up @@ -119,7 +119,7 @@ class InvalidStateException(message: String, cause: Throwable? = null) :
class ResponseStoppedException(val response: GenerateContentResponse, cause: Throwable? = null) :
GoogleGenerativeAIException(
"Content generation stopped. Reason: ${response.candidates.first().finishReason?.name}",
cause
cause,
)

/**
Expand All @@ -130,6 +130,10 @@ class ResponseStoppedException(val response: GenerateContentResponse, cause: Thr
class RequestTimeoutException(message: String, cause: Throwable? = null) :
GoogleGenerativeAIException(message, cause)

/** The quota for this API key is depleted, retry this request at a later time. */
class QuotaExceededException(message: String, cause: Throwable? = null) :
GoogleGenerativeAIException(message, cause)

/** Catch all case for exceptions not explicitly expected. */
class UnknownException(message: String, cause: Throwable? = null) :
GoogleGenerativeAIException(message, cause)

0 comments on commit 47135cf

Please sign in to comment.