package view import ( "errors" "git.ma-al.com/goc_marek/timetracker/app/utils/i18n" "github.com/gofiber/fiber/v3" ) var ( // Typed errors for request validation and authentication ErrInvalidBody = errors.New("invalid request body") ErrNotAuthenticated = errors.New("not authenticated") ErrUserNotFound = errors.New("user not found") ErrUserInactive = errors.New("user account is inactive") ErrInvalidToken = errors.New("invalid token") ErrTokenExpired = errors.New("token has expired") ErrTokenRequired = errors.New("token is required") // Typed errors for logging in and registering ErrInvalidCredentials = errors.New("invalid email or password") ErrEmailNotVerified = errors.New("email not verified") ErrEmailExists = errors.New("email already exists") ErrFirstLastNameRequired = errors.New("first and last name is required") ErrEmailRequired = errors.New("email is required") ErrEmailPasswordRequired = errors.New("email and password are required") ErrRefreshTokenRequired = errors.New("refresh token is required") // Typed errors for password reset ErrInvalidResetToken = errors.New("invalid reset token") ErrResetTokenExpired = errors.New("reset token has expired") ErrPasswordsDoNotMatch = errors.New("passwords do not match") ErrInvalidPassword = errors.New("password must be at least 8 characters long and contain at least one lowercase letter, one uppercase letter, and one digit") ErrTokenPasswordRequired = errors.New("token and password are required") // Typed errors for verification ErrInvalidVerificationToken = errors.New("invalid verification token") ErrVerificationTokenExpired = errors.New("verification token has expired") // Typed errors for data extraction ErrBadRepoIDAttribute = errors.New("invalid repo id attribute") ErrBadYearAttribute = errors.New("invalid year attribute") ErrBadQuarterAttribute = errors.New("invalid quarter attribute") ErrBadPaging = errors.New("invalid paging") ErrInvalidRepoID = errors.New("repo not accessible") ) // Error represents an error with HTTP status code type Error struct { Err error Status int } func (e *Error) Error() string { return e.Err.Error() } func (e *Error) Unwrap() error { return e.Err } // NewError creates a new typed error func NewError(err error, status int) *Error { return &Error{Err: err, Status: status} } // GetErrorCode returns the error code string for HTTP response mapping func GetErrorCode(c fiber.Ctx, err error) string { switch { case errors.Is(err, ErrInvalidBody): return i18n.T_(c, "error.err_invalid_body") case errors.Is(err, ErrInvalidCredentials): return i18n.T_(c, "error.err_invalid_credentials") case errors.Is(err, ErrNotAuthenticated): return i18n.T_(c, "error.err_not_authenticated") case errors.Is(err, ErrUserNotFound): return i18n.T_(c, "error.err_user_not_found") case errors.Is(err, ErrUserInactive): return i18n.T_(c, "error.err_user_inactive") case errors.Is(err, ErrEmailNotVerified): return i18n.T_(c, "error.err_email_not_verified") case errors.Is(err, ErrEmailExists): return i18n.T_(c, "error.err_email_exists") case errors.Is(err, ErrInvalidToken): return i18n.T_(c, "error.err_invalid_token") case errors.Is(err, ErrTokenExpired): return i18n.T_(c, "error.err_token_expired") case errors.Is(err, ErrFirstLastNameRequired): return i18n.T_(c, "error.err_first_last_name_required") case errors.Is(err, ErrEmailRequired): return i18n.T_(c, "error.err_email_required") case errors.Is(err, ErrEmailPasswordRequired): return i18n.T_(c, "error.err_email_password_required") case errors.Is(err, ErrTokenRequired): return i18n.T_(c, "error.err_token_required") case errors.Is(err, ErrRefreshTokenRequired): return i18n.T_(c, "error.err_refresh_token_required") case errors.Is(err, ErrInvalidResetToken): return i18n.T_(c, "error.err_invalid_reset_token") case errors.Is(err, ErrResetTokenExpired): return i18n.T_(c, "error.err_reset_token_expired") case errors.Is(err, ErrPasswordsDoNotMatch): return i18n.T_(c, "error.err_passwords_do_not_match") case errors.Is(err, ErrInvalidPassword): return i18n.T_(c, "error.err_invalid_password") case errors.Is(err, ErrTokenPasswordRequired): return i18n.T_(c, "error.err_token_password_required") case errors.Is(err, ErrInvalidVerificationToken): return i18n.T_(c, "error.err_invalid_verification_token") case errors.Is(err, ErrVerificationTokenExpired): return i18n.T_(c, "error.err_verification_token_expired") case errors.Is(err, ErrBadRepoIDAttribute): return i18n.T_(c, "error.err_bad_repo_id_attribute") case errors.Is(err, ErrBadYearAttribute): return i18n.T_(c, "error.err_bad_year_attribute") case errors.Is(err, ErrBadQuarterAttribute): return i18n.T_(c, "error.err_bad_quarter_attribute") case errors.Is(err, ErrBadPaging): return i18n.T_(c, "error.err_bad_paging") case errors.Is(err, ErrInvalidRepoID): return i18n.T_(c, "error.err_invalid_repo_id") default: return i18n.T_(c, "error.err_internal_server_error") } } // GetErrorStatus returns the HTTP status code for the given error func GetErrorStatus(err error) int { switch { case errors.Is(err, ErrInvalidCredentials), errors.Is(err, ErrNotAuthenticated), errors.Is(err, ErrInvalidToken), errors.Is(err, ErrTokenExpired): return fiber.StatusUnauthorized case errors.Is(err, ErrInvalidBody), errors.Is(err, ErrUserNotFound), errors.Is(err, ErrUserInactive), errors.Is(err, ErrEmailNotVerified), errors.Is(err, ErrFirstLastNameRequired), errors.Is(err, ErrEmailRequired), errors.Is(err, ErrEmailPasswordRequired), errors.Is(err, ErrTokenRequired), errors.Is(err, ErrRefreshTokenRequired), errors.Is(err, ErrPasswordsDoNotMatch), errors.Is(err, ErrTokenPasswordRequired), errors.Is(err, ErrInvalidResetToken), errors.Is(err, ErrResetTokenExpired), errors.Is(err, ErrInvalidVerificationToken), errors.Is(err, ErrVerificationTokenExpired), errors.Is(err, ErrInvalidPassword), errors.Is(err, ErrBadRepoIDAttribute), errors.Is(err, ErrBadYearAttribute), errors.Is(err, ErrBadQuarterAttribute), errors.Is(err, ErrBadPaging), errors.Is(err, ErrInvalidRepoID): return fiber.StatusBadRequest case errors.Is(err, ErrEmailExists): return fiber.StatusConflict default: return fiber.StatusInternalServerError } }