Files
atlas/internal/httpapp/error_handlers.go
othman.suseno df475bc85e
Some checks failed
CI / test-build (push) Failing after 2m11s
logging and diagnostic features added
2025-12-15 00:45:14 +07:00

60 lines
1.8 KiB
Go

package httpapp
import (
"log"
"net/http"
"gitea.avt.data-center.id/othman.suseno/atlas/internal/errors"
)
// writeError writes a structured error response
func writeError(w http.ResponseWriter, err error) {
// Check if it's an APIError
if apiErr, ok := err.(*errors.APIError); ok {
writeJSON(w, apiErr.HTTPStatus, apiErr)
return
}
// Default to internal server error
log.Printf("unhandled error: %v", err)
apiErr := errors.ErrInternal("an unexpected error occurred")
writeJSON(w, apiErr.HTTPStatus, apiErr)
}
// handleServiceError handles errors from service operations with graceful degradation
func (a *App) handleServiceError(serviceName string, err error) error {
if err == nil {
return nil
}
// Log the error for debugging
log.Printf("%s service error: %v", serviceName, err)
// For service errors, we might want to continue operation
// but log the issue. The API request can still succeed
// even if service configuration fails (desired state is stored)
return errors.ErrServiceUnavailable(serviceName).WithDetails(err.Error())
}
// recoverPanic recovers from panics and returns a proper error response
func recoverPanic(w http.ResponseWriter, r *http.Request) {
if rec := recover(); rec != nil {
log.Printf("panic recovered: %v", rec)
err := errors.ErrInternal("an unexpected error occurred")
writeError(w, err)
}
}
// errorMiddleware wraps handlers with panic recovery
func (a *App) errorMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer recoverPanic(w, r)
next.ServeHTTP(w, r)
})
}
// writeJSONError is a convenience function for JSON error responses
func writeJSONError(w http.ResponseWriter, code int, message string) {
writeJSON(w, code, map[string]string{"error": message})
}