Skip to content

Error Handling

All client operations return Result<T> or Result objects for safe error handling.


StatusDescription
200OK - Request succeeded
201Created - Resource created
204No Content - Success, no body
400Bad Request - Invalid parameters
401Unauthorized - Invalid or missing authentication
403Forbidden - Insufficient permissions
404Not Found - Resource doesn’t exist
409Conflict - Condition check failed
429Too Many Requests - Rate limit exceeded
500Internal Server Error

{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.4",
"title": "Not Found",
"status": 404,
"detail": "Item not found",
"instance": "/api/v1/databases/my-db/items/user%23123"
}

var result = await client.GetItemAsync("user#123");
if (result.IsSuccess)
{
var item = result.Value;
// Process item
}
else if (result.IsFailed)
{
foreach (var error in result.Errors)
{
Console.WriteLine($"Error: {error.Message}");
}
}
var result = await client.GetItemAsync("user#123");
if (result.IsFailed)
{
// Handle error
logger.LogError("Failed to get item: {Error}", result.Errors.First().Message);
return null;
}
return result.Value;

var result = await client.GetItemAsync("nonexistent");
if (result.IsFailed && result.Errors.Any(e => e.Message.Contains("not found")))
{
Console.WriteLine("Item does not exist");
}
var result = await client.GetItemAsync("user#123");
if (result.IsFailed && result.Errors.Any(e => e.Message.Contains("unauthorized")))
{
// Refresh token or redirect to login
}
var result = await client.GetItemAsync("user#123");
if (result.IsFailed && result.Errors.Any(e => e.Message.Contains("rate limit")))
{
// Wait and retry
await Task.Delay(TimeSpan.FromSeconds(5));
result = await client.GetItemAsync("user#123");
}
var result = await client.TransactWriteAsync(items);
if (result.IsFailed && result.Errors.Any(e => e.Message.Contains("condition")))
{
// Another process modified the data - refresh and retry
}

{
"successCount": 0,
"errors": [
{
"itemIndex": 2,
"pk": "user#123",
"sk": "settings",
"error": "Condition check failed",
"errorType": "ConditionalCheckFailed"
}
]
}
Error TypeDescription
ConditionalCheckFailedCondition expression evaluated to false
ItemCollectionSizeLimitExceededItem collection too large
TransactionCanceledTransaction was canceled
ValidationErrorInvalid request parameters
InternalServerErrorServer error

The SDK automatically retries transient failures:

  • 429 (Rate Limited)
  • 500, 502, 503, 504 (Server Errors)
  • Network timeouts
  • 400 (Bad Request)
  • 401 (Unauthorized)
  • 403 (Forbidden)
  • 404 (Not Found)
  • 409 (Conflict)
var client = new TerraScaleDatabase(new TerraScaleDatabaseOptions
{
ApiKey = "ts_live_your_api_key",
Endpoint = "https://api.terrascale.io",
Retry = new RetryPolicyOptions
{
MaxRetries = 3,
BaseDelay = TimeSpan.FromMilliseconds(500),
MaxDelay = TimeSpan.FromSeconds(10),
UseJitter = true
}
});

var result = await client.GetItemAsync("user#123");
if (result.IsFailed)
{
foreach (var error in result.Errors)
{
logger.LogError(
"Operation failed: {ErrorType} - {Message}",
error.GetType().Name,
error.Message
);
}
}

  1. Always check results - Never assume success
  2. Log with context - Include operation details in logs
  3. Use specific error handling - Handle known errors differently
  4. Implement retry logic - For transient failures
  5. Fail gracefully - Show user-friendly messages