starter code
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Error is the single shape every failure takes. Clients get a stable machine
|
||||
// readable code plus a human message. A self-hosted bot instance can branch on
|
||||
// the code without parsing prose.
|
||||
type Error struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type errorEnvelope struct {
|
||||
Error Error `json:"error"`
|
||||
}
|
||||
|
||||
const (
|
||||
CodeMissingKey = "missing_key"
|
||||
CodeInvalidKey = "invalid_key"
|
||||
CodeKeyRevoked = "key_revoked"
|
||||
CodeKeySuspended = "key_suspended"
|
||||
CodeKeyExpired = "key_expired"
|
||||
CodeOwnerBlocked = "owner_blocked"
|
||||
CodeForbidden = "insufficient_scope"
|
||||
CodeRateLimited = "rate_limited"
|
||||
CodeInternal = "internal_error"
|
||||
)
|
||||
|
||||
// WriteError sends a JSON error. Deliberately specific about WHY authentication
|
||||
// failed rather than a uniform "unauthorized".
|
||||
//
|
||||
// The usual argument for being vague is to prevent enumeration, but a key is
|
||||
// 256 bits from crypto/rand - there is nothing to enumerate. Telling a
|
||||
// developer their key expired, rather than making them guess, is worth far more
|
||||
// than the non-existent secrecy gained.
|
||||
func WriteError(w http.ResponseWriter, status int, code, message string) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
w.WriteHeader(status)
|
||||
|
||||
if err := json.NewEncoder(w).Encode(errorEnvelope{Error{Code: code, Message: message}}); err != nil {
|
||||
slog.Error("writing error response", "err", err)
|
||||
}
|
||||
}
|
||||
|
||||
// WriteJSON sends a success payload.
|
||||
func WriteJSON(w http.ResponseWriter, status int, v any) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
w.WriteHeader(status)
|
||||
|
||||
if err := json.NewEncoder(w).Encode(v); err != nil {
|
||||
slog.Error("writing response", "err", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user