79 lines
2.1 KiB
Go
79 lines
2.1 KiB
Go
package errors
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"os"
|
|
|
|
chimiddleware "github.com/go-chi/chi/v5/middleware"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
// ErrorCode represents standardized error codes
|
|
type ErrorCode string
|
|
|
|
const (
|
|
CodeUnauthenticated ErrorCode = "UNAUTHENTICATED"
|
|
// More specific authentication error codes
|
|
CodeInvalidCredentials ErrorCode = "INVALID_CREDENTIALS"
|
|
CodeInvalidPassword ErrorCode = "INVALID_PASSWORD"
|
|
|
|
CodePermissionDenied ErrorCode = "PERMISSION_DENIED"
|
|
CodeNotFound ErrorCode = "NOT_FOUND"
|
|
CodeConflict ErrorCode = "CONFLICT"
|
|
CodeAlreadyExists ErrorCode = "ALREADY_EXISTS"
|
|
CodeInvalidArgument ErrorCode = "INVALID_ARGUMENT"
|
|
CodeInternal ErrorCode = "INTERNAL"
|
|
)
|
|
|
|
// ErrorResponse represents the JSON error response structure
|
|
type ErrorResponse struct {
|
|
Code ErrorCode `json:"code"`
|
|
Message string `json:"message"`
|
|
}
|
|
|
|
// WriteError writes a standardized JSON error response
|
|
func WriteError(w http.ResponseWriter, code ErrorCode, message string, status int) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(status)
|
|
json.NewEncoder(w).Encode(ErrorResponse{
|
|
Code: code,
|
|
Message: message,
|
|
})
|
|
}
|
|
|
|
// GetRequestID extracts the request ID from the request context
|
|
func GetRequestID(r *http.Request) string {
|
|
if reqID := chimiddleware.GetReqID(r.Context()); reqID != "" {
|
|
return reqID
|
|
}
|
|
return "unknown"
|
|
}
|
|
|
|
// GetUserID extracts user ID from context if available
|
|
func GetUserID(r *http.Request) string {
|
|
// Use type contextKey matching middleware package
|
|
type contextKey string
|
|
if userID, ok := r.Context().Value(contextKey("user")).(string); ok && userID != "" {
|
|
return userID
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// GetOrgID extracts org ID from context if available
|
|
func GetOrgID(r *http.Request) string {
|
|
if orgID := r.Context().Value("org"); orgID != nil {
|
|
if oid, ok := orgID.(uuid.UUID); ok {
|
|
return oid.String()
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// LogError logs an error with context
|
|
func LogError(r *http.Request, err error, message string) {
|
|
fmt.Fprintf(os.Stderr, "[ERROR] req_id=%s user_id=%s org_id=%s %s: %v\n",
|
|
GetRequestID(r), GetUserID(r), GetOrgID(r), message, err)
|
|
}
|