package main import ( "fmt" "net/http" ) type ErrorCode string const ( // Authentifizierung ErrInvalidCredentials ErrorCode = "INVALID_CREDENTIALS" ErrUnauthorized ErrorCode = "UNAUTHORIZED" ErrTokenExpired ErrorCode = "TOKEN_EXPIRED" ErrAccessDenied ErrorCode = "ACCESS_DENIED" // Validierung ErrInvalidInput ErrorCode = "INVALID_INPUT" ErrMissingField ErrorCode = "MISSING_FIELD" ErrInvalidDateFormat ErrorCode = "INVALID_DATE_FORMAT" ErrInvalidTimeFormat ErrorCode = "INVALID_TIME_FORMAT" // Ressourcen ErrNotFound ErrorCode = "NOT_FOUND" ErrAlreadyExists ErrorCode = "ALREADY_EXISTS" ErrCannotDelete ErrorCode = "CANNOT_DELETE" ErrProtectedUser ErrorCode = "PROTECTED_USER" ErrNoActiveSchool ErrorCode = "NO_ACTIVE_SCHOOL_YEAR" // Datenbank ErrDatabase ErrorCode = "DATABASE_ERROR" ErrTransaction ErrorCode = "TRANSACTION_ERROR" ErrQueryFailed ErrorCode = "QUERY_FAILED" // Server ErrInternal ErrorCode = "INTERNAL_ERROR" ErrServiceUnavail ErrorCode = "SERVICE_UNAVAILABLE" ) type AppError struct { Code ErrorCode `json:"code"` Message string `json:"message"` UserMsg string `json:"user_message"` HTTPStatus int `json:"-"` Internal error `json:"-"` } func (e *AppError) Error() string { if e.Internal != nil { return fmt.Sprintf("[%s] %s: %v", e.Code, e.Message, e.Internal) } return fmt.Sprintf("[%s] %s", e.Code, e.Message) } func NewAppError(code ErrorCode, message, userMsg string, httpStatus int, internal error) *AppError { return &AppError{ Code: code, Message: message, UserMsg: userMsg, HTTPStatus: httpStatus, Internal: internal, } } func ErrInvalidCredentialsMsg() *AppError { return NewAppError( ErrInvalidCredentials, "Invalid username or password", "Benutzername oder Passwort ungültig", http.StatusUnauthorized, nil, ) } func ErrUnauthorizedMsg() *AppError { return NewAppError( ErrUnauthorized, "Unauthorized access", "Keine Berechtigung für diese Aktion", http.StatusUnauthorized, nil, ) } func ErrTokenExpiredMsg() *AppError { return NewAppError( ErrTokenExpired, "Token has expired", "Ihre Sitzung ist abgelaufen. Bitte melden Sie sich erneut an", http.StatusUnauthorized, nil, ) } func ErrAccessDeniedMsg() *AppError { return NewAppError( ErrAccessDenied, "Access denied - admin privileges required", "Zugriff verweigert. Administrator-Rechte erforderlich", http.StatusForbidden, nil, ) } func ErrInvalidInputMsg(field string) *AppError { return NewAppError( ErrInvalidInput, fmt.Sprintf("Invalid input for field: %s", field), fmt.Sprintf("Ungültige Eingabe im Feld: %s", field), http.StatusBadRequest, nil, ) } func ErrMissingFieldMsg(field string) *AppError { return NewAppError( ErrMissingField, fmt.Sprintf("Required field missing: %s", field), fmt.Sprintf("Pflichtfeld fehlt: %s", field), http.StatusBadRequest, nil, ) } func ErrNotFoundMsg(resource string) *AppError { return NewAppError( ErrNotFound, fmt.Sprintf("%s not found", resource), fmt.Sprintf("%s nicht gefunden", resource), http.StatusNotFound, nil, ) } func ErrAlreadyExistsMsg(resource string) *AppError { return NewAppError( ErrAlreadyExists, fmt.Sprintf("%s already exists", resource), fmt.Sprintf("%s existiert bereits", resource), http.StatusConflict, nil, ) } func ErrCannotDeleteMsg(resource, reason string) *AppError { return NewAppError( ErrCannotDelete, fmt.Sprintf("Cannot delete %s: %s", resource, reason), fmt.Sprintf("%s kann nicht gelöscht werden: %s", resource, reason), http.StatusBadRequest, nil, ) } func ErrProtectedUserMsg() *AppError { return NewAppError( ErrProtectedUser, "Cannot modify protected admin user", "Der Admin-Benutzer ist geschützt und kann nicht geändert werden", http.StatusForbidden, nil, ) } func ErrNoActiveSchoolYearMsg() *AppError { return NewAppError( ErrNoActiveSchool, "No active school year configured", "Kein aktives Schuljahr konfiguriert. Bitte aktivieren Sie ein Schuljahr", http.StatusNotFound, nil, ) } func ErrDatabaseMsg(internal error) *AppError { return NewAppError( ErrDatabase, "Database operation failed", "Ein Datenbankfehler ist aufgetreten. Bitte versuchen Sie es erneut", http.StatusInternalServerError, internal, ) } func ErrInternalMsg(internal error) *AppError { return NewAppError( ErrInternal, "Internal server error", "Ein interner Fehler ist aufgetreten. Bitte versuchen Sie es später erneut", http.StatusInternalServerError, internal, ) } type ErrorResponse struct { Code ErrorCode `json:"code"` Message string `json:"message"` } func (e *AppError) ToResponse() ErrorResponse { return ErrorResponse{ Code: e.Code, Message: e.UserMsg, } }