diff --git a/frontend/src/i18n/lang/en.json b/frontend/src/i18n/lang/en.json index 14684433e..6c775b652 100644 --- a/frontend/src/i18n/lang/en.json +++ b/frontend/src/i18n/lang/en.json @@ -1160,6 +1160,7 @@ "1016": "TOTP is not enabled for this user.", "1017": "The TOTP passcode is invalid.", "1018": "The user avatar type setting is invalid.", + "1025": "The timezone '{timezone}' is invalid. Please select a valid timezone from the list.", "2001": "ID cannot be empty or 0.", "2002": "Some of the request data was invalid.", "3001": "The project does not exist.", diff --git a/frontend/src/stores/auth.ts b/frontend/src/stores/auth.ts index 960cb1cb9..99ea7eda1 100644 --- a/frontend/src/stores/auth.ts +++ b/frontend/src/stores/auth.ts @@ -8,7 +8,7 @@ import UserModel, {getAvatarUrl, getDisplayName} from '@/models/user' import UserSettingsService from '@/services/userSettings' import {getToken, refreshToken, removeToken, saveToken} from '@/helpers/auth' import {setModuleLoading} from '@/stores/helper' -import {success} from '@/message' +import {success, error} from '@/message' import { getRedirectUrlFromCurrentFrontendPath, redirectToProvider, @@ -387,7 +387,7 @@ export const useAuthStore = defineStore('auth', () => { success({message: i18n.global.t('user.settings.general.savedSuccess')}) } } catch (e) { - throw new Error('Error while saving user settings:', {cause: e}) + error(e) } finally { cancel() } diff --git a/pkg/user/error.go b/pkg/user/error.go index 3112e5a16..2c536e3b0 100644 --- a/pkg/user/error.go +++ b/pkg/user/error.go @@ -585,3 +585,27 @@ func (err *ErrInvalidClaimData) HTTPError() web.HTTPError { Message: fmt.Sprintf("Invalid claim data for field %s of type %s", err.Field, err.Type), } } + +// ErrInvalidTimezone represents an error where the provided timezone is invalid +type ErrInvalidTimezone struct { + Name string + LoadError error +} + +// IsErrInvalidTimezone checks if an error is a ErrInvalidTimezone. +func IsErrInvalidTimezone(err error) bool { + _, ok := err.(ErrInvalidTimezone) + return ok +} + +func (err ErrInvalidTimezone) Error() string { + return fmt.Sprintf("Invalid timezone [Name: %s, Error: %s]", err.Name, err.LoadError) +} + +// ErrorCodeInvalidTimezone holds the unique world-error code of this error +const ErrorCodeInvalidTimezone = 1025 + +// HTTPError holds the http error description +func (err ErrInvalidTimezone) HTTPError() web.HTTPError { + return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrorCodeInvalidTimezone, Message: fmt.Sprintf("The timezone '%s' is invalid. Please select a valid timezone from the list.", err.Name)} +} diff --git a/pkg/user/user.go b/pkg/user/user.go index 1733e7f75..34f33fe8b 100644 --- a/pkg/user/user.go +++ b/pkg/user/user.go @@ -570,7 +570,7 @@ func UpdateUser(s *xorm.Session, user *User, forceOverride bool) (updatedUser *U _, err = time.LoadLocation(user.Timezone) if err != nil { - return + return nil, &ErrInvalidTimezone{Name: user.Timezone, LoadError: err} } frontendSettingsJSON, err := json.Marshal(user.FrontendSettings)