Models and error handling
For choosing between the sync and async client, see basics.
Claude Models API
List the models currently available to your API key:
//> using dep com.softwaremill.sttp.ai::claude:0.11.0
import sttp.ai.claude.ClaudeSyncClient
object ModelsExample:
def main(args: Array[String]): Unit =
val claude = ClaudeSyncClient.fromEnv
try {
val models = claude.listModels()
models.data.foreach(model => println(s"${model.id} - ${model.displayName}"))
} finally claude.close()
Well-known model ids are available as constants on ClaudeModel (e.g. ClaudeModel.ClaudeSonnet5.value); ClaudeModel.fromString parses a raw id back into a catalogued model.
Claude error handling
ClaudeSyncClient throws subclasses of ClaudeException; the async ClaudeClient returns the same hierarchy in the Left branch of Either[ClaudeException, A]:
//> using dep com.softwaremill.sttp.ai::claude:0.11.0
import sttp.ai.claude.ClaudeSyncClient
import sttp.ai.claude.ClaudeExceptions.ClaudeException
import sttp.ai.claude.models.{ClaudeModel, Message}
import sttp.ai.claude.requests.MessageRequest
object ErrorHandlingExample:
def main(args: Array[String]): Unit =
val claude = ClaudeSyncClient.fromEnv
try {
val request = MessageRequest.simple(ClaudeModel.ClaudeHaiku4_5.value, List(Message.user("Hello!")), 100)
try {
val response = claude.createMessage(request)
println(response.content)
} catch {
case _: ClaudeException.AuthenticationException => println("Authentication failed - check your API key")
case _: ClaudeException.RateLimitException => println("Rate limited - please wait before retrying")
case _: ClaudeException.InvalidRequestException => println("Invalid request - check your parameters")
case _: ClaudeException.PermissionException => println("Permission denied for this resource")
case _: ClaudeException.TryAgain => println("Transient error - retry the request")
case _: ClaudeException.ServiceUnavailableException => println("Claude is temporarily unavailable")
case e: ClaudeException.APIException => println(s"API error: ${e.getMessage}")
case _: ClaudeException.DeserializationClaudeException => println("Failed to parse response")
}
} finally claude.close()
Additionally, structured outputs on an unsupported model throw UnsupportedModelForStructuredOutputException (also under ClaudeExceptions). Note that it extends AIException directly rather than ClaudeException, so a case e: ClaudeException catch-all will not catch it.