This commit is contained in:
59
internal/httpapp/error_handlers.go
Normal file
59
internal/httpapp/error_handlers.go
Normal file
@@ -0,0 +1,59 @@
|
||||
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})
|
||||
}
|
||||
Reference in New Issue
Block a user