Errors
Sentinel errors for storage operations: not found, quota exceeded, driver closed, and more.
Trove defines sentinel errors for all failure cases. Use errors.Is() to match specific error conditions regardless of wrapping.
Resource Errors
Errors related to missing or duplicate resources:
| Error | Description |
|---|---|
ErrNotFound | A requested resource cannot be found |
ErrBucketNotFound | A bucket cannot be found |
ErrBucketExists | Creating a bucket that already exists |
ErrObjectNotFound | An object cannot be found |
Validation Errors
Errors related to invalid input:
| Error | Description |
|---|---|
ErrKeyEmpty | Object key is empty (required field) |
ErrBucketEmpty | Bucket name is empty (required field) |
ErrInvalidDSN | DSN string cannot be parsed |
Driver Errors
Errors related to driver lifecycle:
| Error | Description |
|---|---|
ErrDriverClosed | Operation attempted on a closed driver |
ErrNilDriver | Open called with a nil driver |
ErrBackendNotFound | Named backend does not exist in the router |
Integrity Errors
Errors related to data integrity and security:
| Error | Description |
|---|---|
ErrChecksumMismatch | Checksum verification failed -- data may be corrupted |
ErrContentBlocked | Content rejected by scanning middleware (threat detected) |
Quota Errors
| Error | Description |
|---|---|
ErrQuotaExceeded | Storage quota exceeded for the tenant or bucket |
Stream Errors
Errors related to streaming and upload sessions:
| Error | Description |
|---|---|
ErrStreamClosed | Writing to a closed stream |
ErrStreamNotActive | Operation requires an active stream |
ErrUploadExpired | Resumable upload session has expired |
ErrPoolClosed | Stream pool has been shut down |
ErrMaxStreamsReached | Pool concurrency limit reached |
Matching Errors
Always use errors.Is() to check for sentinel errors, since errors may be wrapped with additional context:
import (
"errors"
"github.com/xraph/trove"
)
reader, err := t.Get(ctx, "data", "report.csv")
if err != nil {
switch {
case errors.Is(err, trove.ErrObjectNotFound):
// Object does not exist -- return 404
http.Error(w, "Not found", http.StatusNotFound)
case errors.Is(err, trove.ErrBucketNotFound):
// Bucket does not exist -- return 404
http.Error(w, "Bucket not found", http.StatusNotFound)
case errors.Is(err, trove.ErrChecksumMismatch):
// Data corruption detected
log.Error("integrity failure", "err", err)
http.Error(w, "Data integrity error", http.StatusInternalServerError)
case errors.Is(err, trove.ErrDriverClosed):
// Driver shut down -- service unavailable
http.Error(w, "Service unavailable", http.StatusServiceUnavailable)
default:
http.Error(w, "Internal error", http.StatusInternalServerError)
}
return
}HTTP Status Code Mapping
When Trove is used as an HTTP API, sentinel errors map to standard HTTP status codes:
| Error | HTTP Status | Code |
|---|---|---|
ErrNotFound | Not Found | 404 |
ErrBucketNotFound | Not Found | 404 |
ErrObjectNotFound | Not Found | 404 |
ErrBucketExists | Conflict | 409 |
ErrKeyEmpty | Bad Request | 400 |
ErrBucketEmpty | Bad Request | 400 |
ErrInvalidDSN | Bad Request | 400 |
ErrDriverClosed | Service Unavailable | 503 |
ErrNilDriver | Internal Server Error | 500 |
ErrBackendNotFound | Not Found | 404 |
ErrChecksumMismatch | Conflict | 409 |
ErrQuotaExceeded | Insufficient Storage | 507 |
ErrContentBlocked | Unprocessable Entity | 422 |
ErrStreamClosed | Gone | 410 |
ErrUploadExpired | Gone | 410 |
ErrPoolClosed | Service Unavailable | 503 |
ErrMaxStreamsReached | Too Many Requests | 429 |
Creating Application Errors
Wrap Trove sentinel errors to add context without losing the ability to match:
import "fmt"
func getDocument(ctx context.Context, t *trove.Trove, docID string) error {
_, err := t.Get(ctx, "documents", docID)
if err != nil {
return fmt.Errorf("get document %s: %w", docID, err)
}
return nil
}
// Callers can still match the original error:
err := getDocument(ctx, t, "missing.pdf")
if errors.Is(err, trove.ErrObjectNotFound) {
// Matched despite wrapping
}