mirror of
https://github.com/go-vikunja/vikunja.git
synced 2026-07-22 12:06:11 -05:00
Parametrised error translations (invalid api token permission, invalid timezone, invalid claim data) rendered their placeholders as empty text because the backend only baked the values into the English message and the frontend translated the error code without any interpolation params. Carry the values as i18n_params on error responses, keyed by the placeholder names of the frontend's error translations, on both v1 and the v2 problem+json body, and pass them through when translating the toast. A 14002 toast now reads e.g. "The permission time_entries of group tasks is invalid." instead of "The permission of group is invalid."
2658 lines
88 KiB
Go
2658 lines
88 KiB
Go
// Vikunja is a to-do list application to facilitate your life.
|
|
// Copyright 2018-present Vikunja and contributors. All rights reserved.
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
package models
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"code.vikunja.io/api/pkg/config"
|
|
"code.vikunja.io/api/pkg/web"
|
|
)
|
|
|
|
// Generic
|
|
|
|
// ErrGenericForbidden represents a "UsernameAlreadyExists" kind of error.
|
|
type ErrGenericForbidden struct{}
|
|
|
|
// IsErrGenericForbidden checks if an error is a ErrGenericForbidden.
|
|
func IsErrGenericForbidden(err error) bool {
|
|
_, ok := err.(ErrGenericForbidden)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrGenericForbidden) Error() string {
|
|
return "Forbidden"
|
|
}
|
|
|
|
// ErrorCodeGenericForbidden holds the unique world-error code of this error
|
|
const ErrorCodeGenericForbidden = 0001
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrGenericForbidden) HTTPError() web.HTTPError {
|
|
return web.HTTPError{HTTPCode: http.StatusForbidden, Code: ErrorCodeGenericForbidden, Message: "You're not allowed to do this."}
|
|
}
|
|
|
|
// ===================
|
|
// Empty things errors
|
|
// ===================
|
|
|
|
// ErrIDCannotBeZero represents a "IDCannotBeZero" kind of error. Used if an ID (of something, not defined) is 0 where it should not.
|
|
type ErrIDCannotBeZero struct{}
|
|
|
|
// IsErrIDCannotBeZero checks if an error is a ErrIDCannotBeZero.
|
|
func IsErrIDCannotBeZero(err error) bool {
|
|
_, ok := err.(ErrIDCannotBeZero)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrIDCannotBeZero) Error() string {
|
|
return "ID cannot be empty or 0"
|
|
}
|
|
|
|
// ErrCodeIDCannotBeZero holds the unique world-error code of this error
|
|
const ErrCodeIDCannotBeZero = 2001
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrIDCannotBeZero) HTTPError() web.HTTPError {
|
|
return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrCodeIDCannotBeZero, Message: "The ID cannot be empty or 0."}
|
|
}
|
|
|
|
// ErrInvalidData represents a "ErrInvalidData" kind of error. Used when a struct is invalid -> validation failed.
|
|
type ErrInvalidData struct {
|
|
Message string
|
|
}
|
|
|
|
// IsErrInvalidData checks if an error is a ErrIDCannotBeZero.
|
|
func IsErrInvalidData(err error) bool {
|
|
_, ok := err.(ErrInvalidData)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrInvalidData) Error() string {
|
|
return fmt.Sprintf("Struct is invalid. %s", err.Message)
|
|
}
|
|
|
|
// ErrCodeInvalidData holds the unique world-error code of this error
|
|
const ErrCodeInvalidData = 2002
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrInvalidData) HTTPError() web.HTTPError {
|
|
return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrCodeInvalidData, Message: err.Message}
|
|
}
|
|
|
|
// ValidationHTTPError is the http error when a validation fails
|
|
type ValidationHTTPError struct {
|
|
web.HTTPError
|
|
InvalidFields []string `json:"invalid_fields"`
|
|
}
|
|
|
|
// Error implements the Error type (so we can return it as type error)
|
|
func (err ValidationHTTPError) Error() string {
|
|
theErr := ErrInvalidData{
|
|
Message: err.Message,
|
|
}
|
|
return theErr.Error()
|
|
}
|
|
|
|
// MarshalJSON implements json.Marshaler to ensure InvalidFields is included in the JSON response.
|
|
// This is needed because Echo's DefaultHTTPErrorHandler converts error types to {"message": err.Error()},
|
|
// losing structured data. By implementing json.Marshaler, Echo will serialize the full struct.
|
|
func (err ValidationHTTPError) MarshalJSON() ([]byte, error) {
|
|
return json.Marshal(struct {
|
|
Code int `json:"code"`
|
|
Message string `json:"message"`
|
|
InvalidFields []string `json:"invalid_fields"`
|
|
}{
|
|
Code: err.Code,
|
|
Message: err.Message,
|
|
InvalidFields: err.InvalidFields,
|
|
})
|
|
}
|
|
|
|
// GetHTTPCode returns the HTTP status code for this error.
|
|
func (err ValidationHTTPError) GetHTTPCode() int {
|
|
return err.HTTPCode
|
|
}
|
|
|
|
// GetCode returns Vikunja's numeric domain error code. v2's translateDomainError
|
|
// reads it to keep the v1 `code` body contract, since this type does not
|
|
// implement web.HTTPErrorProcessor (the embedded field shadows the method name).
|
|
func (err ValidationHTTPError) GetCode() int {
|
|
return err.Code
|
|
}
|
|
|
|
func InvalidFieldError(fields []string) error {
|
|
return InvalidFieldErrorWithMessage(fields, "Invalid Data")
|
|
}
|
|
|
|
func InvalidFieldErrorWithMessage(fields []string, message string) error {
|
|
return ValidationHTTPError{
|
|
HTTPError: web.HTTPError{
|
|
HTTPCode: http.StatusPreconditionFailed,
|
|
Code: ErrCodeInvalidData,
|
|
Message: message,
|
|
},
|
|
InvalidFields: fields,
|
|
}
|
|
}
|
|
|
|
// ErrInvalidTimezone represents a "InvalidTimezone" kind of error.
|
|
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: %s, err: %v", err.Name, err.LoadError)
|
|
}
|
|
|
|
// ErrCodeInvalidTimezone holds the unique world-error code of this error
|
|
const ErrCodeInvalidTimezone = 2003
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrInvalidTimezone) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeInvalidTimezone,
|
|
Message: fmt.Sprintf("The timezone '%s' is invalid", err.Name),
|
|
I18nParams: map[string]string{"timezone": err.Name},
|
|
}
|
|
}
|
|
|
|
// ErrInvalidModel represents an error where the request body could not be parsed
|
|
type ErrInvalidModel struct {
|
|
Message string
|
|
Err error // Original error for unwrapping
|
|
}
|
|
|
|
// IsErrInvalidModel checks if an error is ErrInvalidModel.
|
|
func IsErrInvalidModel(err error) bool {
|
|
_, ok := err.(ErrInvalidModel)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrInvalidModel) Error() string {
|
|
if err.Message != "" {
|
|
return fmt.Sprintf("Invalid model provided: %s", err.Message)
|
|
}
|
|
return "Invalid model provided."
|
|
}
|
|
|
|
// Unwrap returns the wrapped error for use with errors.Is/errors.As
|
|
func (err ErrInvalidModel) Unwrap() error {
|
|
return err.Err
|
|
}
|
|
|
|
// ErrCodeInvalidModel holds the unique world-error code of this error
|
|
const ErrCodeInvalidModel = 2004
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrInvalidModel) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeInvalidModel,
|
|
Message: err.Error(),
|
|
}
|
|
}
|
|
|
|
// ===========
|
|
// Project errors
|
|
// ===========
|
|
|
|
// ErrProjectDoesNotExist represents a "ErrProjectDoesNotExist" kind of error. Used if the project does not exist.
|
|
type ErrProjectDoesNotExist struct {
|
|
ID int64
|
|
}
|
|
|
|
// IsErrProjectDoesNotExist checks if an error is a ErrProjectDoesNotExist.
|
|
func IsErrProjectDoesNotExist(err error) bool {
|
|
_, ok := err.(ErrProjectDoesNotExist)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrProjectDoesNotExist) Error() string {
|
|
return fmt.Sprintf("Project does not exist [ID: %d]", err.ID)
|
|
}
|
|
|
|
// ErrCodeProjectDoesNotExist holds the unique world-error code of this error
|
|
const ErrCodeProjectDoesNotExist = 3001
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrProjectDoesNotExist) HTTPError() web.HTTPError {
|
|
return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeProjectDoesNotExist, Message: "This project does not exist."}
|
|
}
|
|
|
|
// ErrNeedToHaveProjectReadAccess represents an error, where the user dont has read access to that Project
|
|
type ErrNeedToHaveProjectReadAccess struct {
|
|
ProjectID int64
|
|
UserID int64
|
|
}
|
|
|
|
// IsErrNeedToHaveProjectReadAccess checks if an error is a ErrProjectDoesNotExist.
|
|
func IsErrNeedToHaveProjectReadAccess(err error) bool {
|
|
_, ok := err.(ErrNeedToHaveProjectReadAccess)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrNeedToHaveProjectReadAccess) Error() string {
|
|
return fmt.Sprintf("User needs to have read access to that project [ProjectID: %d, ID: %d]", err.ProjectID, err.UserID)
|
|
}
|
|
|
|
// ErrCodeNeedToHaveProjectReadAccess holds the unique world-error code of this error
|
|
const ErrCodeNeedToHaveProjectReadAccess = 3004
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrNeedToHaveProjectReadAccess) HTTPError() web.HTTPError {
|
|
return web.HTTPError{HTTPCode: http.StatusForbidden, Code: ErrCodeNeedToHaveProjectReadAccess, Message: "You need to have read access to this project."}
|
|
}
|
|
|
|
// ErrProjectTitleCannotBeEmpty represents a "ErrProjectTitleCannotBeEmpty" kind of error. Used if the project does not exist.
|
|
type ErrProjectTitleCannotBeEmpty struct{}
|
|
|
|
// IsErrProjectTitleCannotBeEmpty checks if an error is a ErrProjectTitleCannotBeEmpty.
|
|
func IsErrProjectTitleCannotBeEmpty(err error) bool {
|
|
_, ok := err.(ErrProjectTitleCannotBeEmpty)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrProjectTitleCannotBeEmpty) Error() string {
|
|
return "Project title cannot be empty."
|
|
}
|
|
|
|
// ErrCodeProjectTitleCannotBeEmpty holds the unique world-error code of this error
|
|
const ErrCodeProjectTitleCannotBeEmpty = 3005
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrProjectTitleCannotBeEmpty) HTTPError() web.HTTPError {
|
|
return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrCodeProjectTitleCannotBeEmpty, Message: "You must provide at least a project title."}
|
|
}
|
|
|
|
// ErrProjectShareDoesNotExist represents a "ErrProjectShareDoesNotExist" kind of error. Used if the project share does not exist.
|
|
type ErrProjectShareDoesNotExist struct {
|
|
ID int64
|
|
Hash string
|
|
}
|
|
|
|
// IsErrProjectShareDoesNotExist checks if an error is a ErrProjectShareDoesNotExist.
|
|
func IsErrProjectShareDoesNotExist(err error) bool {
|
|
_, ok := err.(ErrProjectShareDoesNotExist)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrProjectShareDoesNotExist) Error() string {
|
|
return "Project share does not exist."
|
|
}
|
|
|
|
// ErrCodeProjectShareDoesNotExist holds the unique world-error code of this error
|
|
const ErrCodeProjectShareDoesNotExist = 3006
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrProjectShareDoesNotExist) HTTPError() web.HTTPError {
|
|
return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeProjectShareDoesNotExist, Message: "The project share does not exist."}
|
|
}
|
|
|
|
// ErrProjectIdentifierIsNotUnique represents a "ErrProjectIdentifierIsNotUnique" kind of error. Used if the provided project identifier is not unique.
|
|
type ErrProjectIdentifierIsNotUnique struct {
|
|
Identifier string
|
|
}
|
|
|
|
// IsErrProjectIdentifierIsNotUnique checks if an error is a ErrProjectIdentifierIsNotUnique.
|
|
func IsErrProjectIdentifierIsNotUnique(err error) bool {
|
|
_, ok := err.(ErrProjectIdentifierIsNotUnique)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrProjectIdentifierIsNotUnique) Error() string {
|
|
return "Project identifier is not unique."
|
|
}
|
|
|
|
// ErrCodeProjectIdentifierIsNotUnique holds the unique world-error code of this error
|
|
const ErrCodeProjectIdentifierIsNotUnique = 3007
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrProjectIdentifierIsNotUnique) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeProjectIdentifierIsNotUnique,
|
|
Message: "A project with this identifier already exists.",
|
|
}
|
|
}
|
|
|
|
// ErrProjectIsArchived represents an error, where a project is archived
|
|
type ErrProjectIsArchived struct {
|
|
ProjectID int64
|
|
}
|
|
|
|
// IsErrProjectIsArchived checks if an error is a project is archived error.
|
|
func IsErrProjectIsArchived(err error) bool {
|
|
_, ok := err.(ErrProjectIsArchived)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrProjectIsArchived) Error() string {
|
|
return fmt.Sprintf("Project is archived [ProjectID: %d]", err.ProjectID)
|
|
}
|
|
|
|
// ErrCodeProjectIsArchived holds the unique world-error code of this error
|
|
const ErrCodeProjectIsArchived = 3008
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrProjectIsArchived) HTTPError() web.HTTPError {
|
|
return web.HTTPError{HTTPCode: http.StatusPreconditionFailed, Code: ErrCodeProjectIsArchived, Message: "This project is archived. Editing or creating new tasks is not possible."}
|
|
}
|
|
|
|
// ErrProjectCannotBelongToAPseudoParentProject represents an error where a project cannot belong to a pseudo project
|
|
type ErrProjectCannotBelongToAPseudoParentProject struct {
|
|
ProjectID int64
|
|
ParentProjectID int64
|
|
}
|
|
|
|
// IsErrProjectCannotBelongToAPseudoParentProject checks if an error is a project is archived error.
|
|
func IsErrProjectCannotBelongToAPseudoParentProject(err error) bool {
|
|
_, ok := err.(*ErrProjectCannotBelongToAPseudoParentProject)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrProjectCannotBelongToAPseudoParentProject) Error() string {
|
|
return fmt.Sprintf("Project cannot belong to a pseudo parent project [ProjectID: %d, ParentProjectID: %d]", err.ProjectID, err.ParentProjectID)
|
|
}
|
|
|
|
// ErrCodeProjectCannotBelongToAPseudoParentProject holds the unique world-error code of this error
|
|
const ErrCodeProjectCannotBelongToAPseudoParentProject = 3009
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrProjectCannotBelongToAPseudoParentProject) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusPreconditionFailed,
|
|
Code: ErrCodeProjectCannotBelongToAPseudoParentProject,
|
|
Message: "This project cannot belong a dynamically generated project.",
|
|
}
|
|
}
|
|
|
|
// ErrProjectCannotBeChildOfItself represents an error where a project cannot become a child of its own
|
|
type ErrProjectCannotBeChildOfItself struct {
|
|
ProjectID int64
|
|
}
|
|
|
|
// IsErrProjectCannotBeChildOfItsOwn checks if an error is a project is archived error.
|
|
func IsErrProjectCannotBeChildOfItsOwn(err error) bool {
|
|
_, ok := err.(*ErrProjectCannotBeChildOfItself)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrProjectCannotBeChildOfItself) Error() string {
|
|
return fmt.Sprintf("Project cannot be made a child of itself [ProjectID: %d]", err.ProjectID)
|
|
}
|
|
|
|
// ErrCodeProjectCannotBeChildOfItself holds the unique world-error code of this error
|
|
const ErrCodeProjectCannotBeChildOfItself = 3010
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrProjectCannotBeChildOfItself) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusPreconditionFailed,
|
|
Code: ErrCodeProjectCannotBeChildOfItself,
|
|
Message: "This project cannot be a child of itself.",
|
|
}
|
|
}
|
|
|
|
// ErrProjectCannotHaveACyclicRelationship represents an error where a project cannot have a cyclic parent relationship
|
|
type ErrProjectCannotHaveACyclicRelationship struct {
|
|
ProjectID int64
|
|
CycleIDs []int64
|
|
}
|
|
|
|
// IsErrProjectCannotHaveACyclicRelationship checks if an error is a project is archived error.
|
|
func IsErrProjectCannotHaveACyclicRelationship(err error) bool {
|
|
_, ok := err.(*ErrProjectCannotHaveACyclicRelationship)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrProjectCannotHaveACyclicRelationship) CycleString() string {
|
|
var cycle string
|
|
for _, projectID := range err.CycleIDs {
|
|
cycle += fmt.Sprintf("%d -> ", projectID)
|
|
}
|
|
return strings.TrimSuffix(cycle, " -> ")
|
|
}
|
|
|
|
func (err *ErrProjectCannotHaveACyclicRelationship) Error() string {
|
|
return fmt.Sprintf("Project cannot have a cyclic relationship [ProjectID: %d]", err.ProjectID)
|
|
}
|
|
|
|
// ErrCodeProjectCannotHaveACyclicRelationship holds the unique world-error code of this error
|
|
const ErrCodeProjectCannotHaveACyclicRelationship = 3011
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrProjectCannotHaveACyclicRelationship) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusPreconditionFailed,
|
|
Code: ErrCodeProjectCannotHaveACyclicRelationship,
|
|
Message: "This project cannot have a cyclic relationship to a parent project.",
|
|
}
|
|
}
|
|
|
|
// ErrCannotDeleteDefaultProject represents an error where the default project is being deleted
|
|
type ErrCannotDeleteDefaultProject struct {
|
|
ProjectID int64
|
|
}
|
|
|
|
// IsErrCannotDeleteDefaultProject checks if an error is a project is archived error.
|
|
func IsErrCannotDeleteDefaultProject(err error) bool {
|
|
_, ok := err.(*ErrCannotDeleteDefaultProject)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrCannotDeleteDefaultProject) Error() string {
|
|
return fmt.Sprintf("Default project cannot be deleted [ProjectID: %d]", err.ProjectID)
|
|
}
|
|
|
|
// ErrCodeCannotDeleteDefaultProject holds the unique world-error code of this error
|
|
const ErrCodeCannotDeleteDefaultProject = 3012
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrCannotDeleteDefaultProject) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusPreconditionFailed,
|
|
Code: ErrCodeCannotDeleteDefaultProject,
|
|
Message: "This project cannot be deleted because it is the default project of a user.",
|
|
}
|
|
}
|
|
|
|
// ErrCannotArchiveDefaultProject represents an error where the default project is being deleted
|
|
type ErrCannotArchiveDefaultProject struct {
|
|
ProjectID int64
|
|
}
|
|
|
|
// IsErrCannotArchiveDefaultProject checks if an error is a project is archived error.
|
|
func IsErrCannotArchiveDefaultProject(err error) bool {
|
|
_, ok := err.(*ErrCannotArchiveDefaultProject)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrCannotArchiveDefaultProject) Error() string {
|
|
return fmt.Sprintf("Default project cannot be archived [ProjectID: %d]", err.ProjectID)
|
|
}
|
|
|
|
// ErrCodeCannotArchiveDefaultProject holds the unique world-error code of this error
|
|
const ErrCodeCannotArchiveDefaultProject = 3013
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrCannotArchiveDefaultProject) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusPreconditionFailed,
|
|
Code: ErrCodeCannotArchiveDefaultProject,
|
|
Message: "This project cannot be archived because it is the default project of a user.",
|
|
}
|
|
}
|
|
|
|
// ErrProjectViewDoesNotExist represents an error where the default project is being deleted
|
|
type ErrProjectViewDoesNotExist struct {
|
|
ProjectViewID int64
|
|
}
|
|
|
|
// IsErrProjectViewDoesNotExist checks if an error is a project is archived error.
|
|
func IsErrProjectViewDoesNotExist(err error) bool {
|
|
_, ok := err.(*ErrProjectViewDoesNotExist)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrProjectViewDoesNotExist) Error() string {
|
|
return fmt.Sprintf("Project view does not exist [ProjectViewID: %d]", err.ProjectViewID)
|
|
}
|
|
|
|
// ErrCodeProjectViewDoesNotExist holds the unique world-error code of this error
|
|
const ErrCodeProjectViewDoesNotExist = 3014
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrProjectViewDoesNotExist) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusNotFound,
|
|
Code: ErrCodeProjectViewDoesNotExist,
|
|
Message: "This project view does not exist.",
|
|
}
|
|
}
|
|
|
|
// ErrProjectHasNoBackground represents an error where a project has no background set.
|
|
type ErrProjectHasNoBackground struct {
|
|
ProjectID int64
|
|
}
|
|
|
|
// IsErrProjectHasNoBackground checks if an error is ErrProjectHasNoBackground.
|
|
func IsErrProjectHasNoBackground(err error) bool {
|
|
_, ok := err.(*ErrProjectHasNoBackground)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrProjectHasNoBackground) Error() string {
|
|
return fmt.Sprintf("Project has no background [ProjectID: %d]", err.ProjectID)
|
|
}
|
|
|
|
// ErrCodeProjectHasNoBackground holds the unique world-error code of this error
|
|
const ErrCodeProjectHasNoBackground = 3015
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrProjectHasNoBackground) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusNotFound,
|
|
Code: ErrCodeProjectHasNoBackground,
|
|
// Message kept verbatim from v1's inline handler error so the wire body is unchanged.
|
|
Message: "Project background not found",
|
|
}
|
|
}
|
|
|
|
// ==============
|
|
// Task errors
|
|
// ==============
|
|
|
|
// ErrTaskCannotBeEmpty represents a "ErrTaskCannotBeEmpty" kind of error.
|
|
type ErrTaskCannotBeEmpty struct{}
|
|
|
|
// IsErrTaskCannotBeEmpty checks if an error is a ErrProjectDoesNotExist.
|
|
func IsErrTaskCannotBeEmpty(err error) bool {
|
|
_, ok := err.(ErrTaskCannotBeEmpty)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrTaskCannotBeEmpty) Error() string {
|
|
return "Task title cannot be empty."
|
|
}
|
|
|
|
// ErrCodeTaskCannotBeEmpty holds the unique world-error code of this error
|
|
const ErrCodeTaskCannotBeEmpty = 4001
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrTaskCannotBeEmpty) HTTPError() web.HTTPError {
|
|
return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrCodeTaskCannotBeEmpty, Message: "You must provide at least a task title."}
|
|
}
|
|
|
|
// ErrInvalidTaskRepeatInterval represents an error where the provided
|
|
// task repeat interval is outside the allowed range.
|
|
type ErrInvalidTaskRepeatInterval struct {
|
|
RepeatAfter int64
|
|
}
|
|
|
|
// IsErrInvalidTaskRepeatInterval checks if an error is ErrInvalidTaskRepeatInterval.
|
|
func IsErrInvalidTaskRepeatInterval(err error) bool {
|
|
_, ok := err.(ErrInvalidTaskRepeatInterval)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrInvalidTaskRepeatInterval) Error() string {
|
|
return fmt.Sprintf("Invalid task repeat interval. [RepeatAfter: %d]", err.RepeatAfter)
|
|
}
|
|
|
|
// ErrCodeInvalidTaskRepeatInterval holds the unique world-error code of this error.
|
|
const ErrCodeInvalidTaskRepeatInterval = 4029
|
|
|
|
// HTTPError holds the http error description.
|
|
func (err ErrInvalidTaskRepeatInterval) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeInvalidTaskRepeatInterval,
|
|
Message: fmt.Sprintf("The task repeat interval must be between 0 and %d seconds (10 years).", MaxTaskRepeatAfterSeconds),
|
|
}
|
|
}
|
|
|
|
// ErrTaskDoesNotExist represents a "ErrProjectDoesNotExist" kind of error. Used if the project does not exist.
|
|
type ErrTaskDoesNotExist struct {
|
|
ID int64
|
|
}
|
|
|
|
// IsErrTaskDoesNotExist checks if an error is a ErrProjectDoesNotExist.
|
|
func IsErrTaskDoesNotExist(err error) bool {
|
|
_, ok := err.(ErrTaskDoesNotExist)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrTaskDoesNotExist) Error() string {
|
|
return fmt.Sprintf("The task does not exist. [ID: %d]", err.ID)
|
|
}
|
|
|
|
// ErrCodeTaskDoesNotExist holds the unique world-error code of this error
|
|
const ErrCodeTaskDoesNotExist = 4002
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrTaskDoesNotExist) HTTPError() web.HTTPError {
|
|
return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTaskDoesNotExist, Message: "This task does not exist"}
|
|
}
|
|
|
|
// ErrBulkTasksMustBeInSameProject represents a "ErrBulkTasksMustBeInSameProject" kind of error.
|
|
type ErrBulkTasksMustBeInSameProject struct {
|
|
ShouldBeID int64
|
|
IsID int64
|
|
}
|
|
|
|
// IsErrBulkTasksMustBeInSameProject checks if an error is a ErrBulkTasksMustBeInSameProject.
|
|
func IsErrBulkTasksMustBeInSameProject(err error) bool {
|
|
_, ok := err.(ErrBulkTasksMustBeInSameProject)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrBulkTasksMustBeInSameProject) Error() string {
|
|
return fmt.Sprintf("All bulk editing tasks must be in the same project. [Should be: %d, is: %d]", err.ShouldBeID, err.IsID)
|
|
}
|
|
|
|
// ErrCodeBulkTasksMustBeInSameProject holds the unique world-error code of this error
|
|
const ErrCodeBulkTasksMustBeInSameProject = 4003
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrBulkTasksMustBeInSameProject) HTTPError() web.HTTPError {
|
|
return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrCodeBulkTasksMustBeInSameProject, Message: "All tasks must be in the same project."}
|
|
}
|
|
|
|
// ErrBulkTasksNeedAtLeastOne represents a "ErrBulkTasksNeedAtLeastOne" kind of error.
|
|
type ErrBulkTasksNeedAtLeastOne struct{}
|
|
|
|
// IsErrBulkTasksNeedAtLeastOne checks if an error is a ErrBulkTasksNeedAtLeastOne.
|
|
func IsErrBulkTasksNeedAtLeastOne(err error) bool {
|
|
_, ok := err.(ErrBulkTasksNeedAtLeastOne)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrBulkTasksNeedAtLeastOne) Error() string {
|
|
return "Need at least one task when bulk editing tasks"
|
|
}
|
|
|
|
// ErrCodeBulkTasksNeedAtLeastOne holds the unique world-error code of this error
|
|
const ErrCodeBulkTasksNeedAtLeastOne = 4004
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrBulkTasksNeedAtLeastOne) HTTPError() web.HTTPError {
|
|
return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrCodeBulkTasksNeedAtLeastOne, Message: "Need at least one tasks to do bulk editing."}
|
|
}
|
|
|
|
// ErrNoPermissionToSeeTask represents an error where a user does not have the permission to see a task
|
|
type ErrNoPermissionToSeeTask struct {
|
|
TaskID int64
|
|
UserID int64
|
|
}
|
|
|
|
// IsErrNoPermissionToSeeTask checks if an error is ErrNoPermissionToSeeTask.
|
|
func IsErrNoPermissionToSeeTask(err error) bool {
|
|
_, ok := err.(ErrNoPermissionToSeeTask)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrNoPermissionToSeeTask) Error() string {
|
|
return fmt.Sprintf("User does not have the permission to see the task [TaskID: %v, ID: %v]", err.TaskID, err.UserID)
|
|
}
|
|
|
|
// ErrCodeNoRightToSeeTask holds the unique world-error code of this error
|
|
const ErrCodeNoRightToSeeTask = 4005
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrNoPermissionToSeeTask) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusForbidden,
|
|
Code: ErrCodeNoRightToSeeTask,
|
|
Message: "You don't have the permission to see this task.",
|
|
}
|
|
}
|
|
|
|
// ErrParentTaskCannotBeTheSame represents an error where the user tries to set a tasks parent as the same
|
|
type ErrParentTaskCannotBeTheSame struct {
|
|
TaskID int64
|
|
}
|
|
|
|
// IsErrParentTaskCannotBeTheSame checks if an error is ErrParentTaskCannotBeTheSame.
|
|
func IsErrParentTaskCannotBeTheSame(err error) bool {
|
|
_, ok := err.(ErrParentTaskCannotBeTheSame)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrParentTaskCannotBeTheSame) Error() string {
|
|
return fmt.Sprintf("Tried to set a parents task as the same [TaskID: %v]", err.TaskID)
|
|
}
|
|
|
|
// ErrCodeParentTaskCannotBeTheSame holds the unique world-error code of this error
|
|
const ErrCodeParentTaskCannotBeTheSame = 4006
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrParentTaskCannotBeTheSame) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusForbidden,
|
|
Code: ErrCodeParentTaskCannotBeTheSame,
|
|
Message: "You cannot set a parent task to the task itself.",
|
|
}
|
|
}
|
|
|
|
// ErrInvalidRelationKind represents an error where the user tries to use an invalid relation kind
|
|
type ErrInvalidRelationKind struct {
|
|
Kind RelationKind
|
|
}
|
|
|
|
// IsErrInvalidRelationKind checks if an error is ErrInvalidRelationKind.
|
|
func IsErrInvalidRelationKind(err error) bool {
|
|
_, ok := err.(ErrInvalidRelationKind)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrInvalidRelationKind) Error() string {
|
|
return fmt.Sprintf("Invalid task relation kind [Kind: %v]", err.Kind)
|
|
}
|
|
|
|
// ErrCodeInvalidRelationKind holds the unique world-error code of this error
|
|
const ErrCodeInvalidRelationKind = 4007
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrInvalidRelationKind) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeInvalidRelationKind,
|
|
Message: "The task relation is invalid.",
|
|
}
|
|
}
|
|
|
|
// ErrRelationAlreadyExists represents an error where the user tries to create an already existing relation
|
|
type ErrRelationAlreadyExists struct {
|
|
Kind RelationKind
|
|
TaskID int64
|
|
OtherTaskID int64
|
|
}
|
|
|
|
// IsErrRelationAlreadyExists checks if an error is ErrRelationAlreadyExists.
|
|
func IsErrRelationAlreadyExists(err error) bool {
|
|
_, ok := err.(ErrRelationAlreadyExists)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrRelationAlreadyExists) Error() string {
|
|
return fmt.Sprintf("Task relation already exists [TaskID: %v, OtherTaskID: %v, Kind: %v]", err.TaskID, err.OtherTaskID, err.Kind)
|
|
}
|
|
|
|
// ErrCodeRelationAlreadyExists holds the unique world-error code of this error
|
|
const ErrCodeRelationAlreadyExists = 4008
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrRelationAlreadyExists) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusConflict,
|
|
Code: ErrCodeRelationAlreadyExists,
|
|
Message: "The task relation already exists.",
|
|
}
|
|
}
|
|
|
|
// ErrRelationDoesNotExist represents an error where a task relation does not exist.
|
|
type ErrRelationDoesNotExist struct {
|
|
Kind RelationKind
|
|
TaskID int64
|
|
OtherTaskID int64
|
|
}
|
|
|
|
// IsErrRelationDoesNotExist checks if an error is ErrRelationDoesNotExist.
|
|
func IsErrRelationDoesNotExist(err error) bool {
|
|
_, ok := err.(ErrRelationDoesNotExist)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrRelationDoesNotExist) Error() string {
|
|
return fmt.Sprintf("Task relation does not exist [TaskID: %v, OtherTaskID: %v, Kind: %v]", err.TaskID, err.OtherTaskID, err.Kind)
|
|
}
|
|
|
|
// ErrCodeRelationDoesNotExist holds the unique world-error code of this error
|
|
const ErrCodeRelationDoesNotExist = 4009
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrRelationDoesNotExist) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusNotFound,
|
|
Code: ErrCodeRelationDoesNotExist,
|
|
Message: "The task relation does not exist.",
|
|
}
|
|
}
|
|
|
|
// ErrRelationTasksCannotBeTheSame represents an error where the user tries to relate a task with itself
|
|
type ErrRelationTasksCannotBeTheSame struct {
|
|
TaskID int64
|
|
OtherTaskID int64
|
|
}
|
|
|
|
// IsErrRelationTasksCannotBeTheSame checks if an error is ErrRelationTasksCannotBeTheSame.
|
|
func IsErrRelationTasksCannotBeTheSame(err error) bool {
|
|
_, ok := err.(ErrRelationTasksCannotBeTheSame)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrRelationTasksCannotBeTheSame) Error() string {
|
|
return fmt.Sprintf("Tried to relate a task with itself [TaskID: %v, OtherTaskID: %v]", err.TaskID, err.OtherTaskID)
|
|
}
|
|
|
|
// ErrCodeRelationTasksCannotBeTheSame holds the unique world-error code of this error
|
|
const ErrCodeRelationTasksCannotBeTheSame = 4010
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrRelationTasksCannotBeTheSame) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeRelationTasksCannotBeTheSame,
|
|
Message: "You cannot relate a task with itself",
|
|
}
|
|
}
|
|
|
|
// ErrTaskAttachmentDoesNotExist represents an error where the user tries to relate a task with itself
|
|
type ErrTaskAttachmentDoesNotExist struct {
|
|
TaskID int64
|
|
AttachmentID int64
|
|
FileID int64
|
|
}
|
|
|
|
// IsErrTaskAttachmentDoesNotExist checks if an error is ErrTaskAttachmentDoesNotExist.
|
|
func IsErrTaskAttachmentDoesNotExist(err error) bool {
|
|
_, ok := err.(ErrTaskAttachmentDoesNotExist)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrTaskAttachmentDoesNotExist) Error() string {
|
|
return fmt.Sprintf("Task attachment does not exist [TaskID: %d, AttachmentID: %d, FileID: %d]", err.TaskID, err.AttachmentID, err.FileID)
|
|
}
|
|
|
|
// ErrCodeTaskAttachmentDoesNotExist holds the unique world-error code of this error
|
|
const ErrCodeTaskAttachmentDoesNotExist = 4011
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrTaskAttachmentDoesNotExist) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusNotFound,
|
|
Code: ErrCodeTaskAttachmentDoesNotExist,
|
|
Message: "This task attachment does not exist.",
|
|
}
|
|
}
|
|
|
|
// ErrTaskAttachmentIsTooLarge represents an error where the user tries to relate a task with itself
|
|
type ErrTaskAttachmentIsTooLarge struct {
|
|
Size uint64
|
|
}
|
|
|
|
// IsErrTaskAttachmentIsTooLarge checks if an error is ErrTaskAttachmentIsTooLarge.
|
|
func IsErrTaskAttachmentIsTooLarge(err error) bool {
|
|
_, ok := err.(ErrTaskAttachmentIsTooLarge)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrTaskAttachmentIsTooLarge) Error() string {
|
|
return fmt.Sprintf("Task attachment is too large [Size: %d]", err.Size)
|
|
}
|
|
|
|
// ErrCodeTaskAttachmentIsTooLarge holds the unique world-error code of this error
|
|
const ErrCodeTaskAttachmentIsTooLarge = 4012
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrTaskAttachmentIsTooLarge) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeTaskAttachmentIsTooLarge,
|
|
Message: fmt.Sprintf("The task attachment exceeds the configured file size of %d bytes, filesize was %d", config.FilesMaxSize.GetInt64(), err.Size),
|
|
}
|
|
}
|
|
|
|
// ErrInvalidSortParam represents an error where the provided sort param is invalid
|
|
type ErrInvalidSortParam struct {
|
|
SortBy string
|
|
}
|
|
|
|
// IsErrInvalidSortParam checks if an error is ErrInvalidSortParam.
|
|
func IsErrInvalidSortParam(err error) bool {
|
|
_, ok := err.(ErrInvalidSortParam)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrInvalidSortParam) Error() string {
|
|
return fmt.Sprintf("Sort param is invalid [SortBy: %s]", err.SortBy)
|
|
}
|
|
|
|
// ErrCodeInvalidSortParam holds the unique world-error code of this error
|
|
const ErrCodeInvalidSortParam = 4013
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrInvalidSortParam) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeInvalidSortParam,
|
|
Message: fmt.Sprintf("The task sort param '%s' is invalid.", err.SortBy),
|
|
}
|
|
}
|
|
|
|
// ErrInvalidSortOrder represents an error where the provided sort order is invalid
|
|
type ErrInvalidSortOrder struct {
|
|
OrderBy sortOrder
|
|
}
|
|
|
|
// IsErrInvalidSortOrder checks if an error is ErrInvalidSortOrder.
|
|
func IsErrInvalidSortOrder(err error) bool {
|
|
_, ok := err.(ErrInvalidSortOrder)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrInvalidSortOrder) Error() string {
|
|
return fmt.Sprintf("Sort order is invalid [OrderBy: %s]", err.OrderBy)
|
|
}
|
|
|
|
// ErrCodeInvalidSortOrder holds the unique world-error code of this error
|
|
const ErrCodeInvalidSortOrder = 4014
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrInvalidSortOrder) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeInvalidSortOrder,
|
|
Message: fmt.Sprintf("The task sort order '%s' is invalid. Allowed is either asc or desc.", err.OrderBy),
|
|
}
|
|
}
|
|
|
|
// ErrTaskCommentDoesNotExist represents an error where a task comment does not exist
|
|
type ErrTaskCommentDoesNotExist struct {
|
|
ID int64
|
|
TaskID int64
|
|
}
|
|
|
|
// IsErrTaskCommentDoesNotExist checks if an error is ErrTaskCommentDoesNotExist.
|
|
func IsErrTaskCommentDoesNotExist(err error) bool {
|
|
_, ok := err.(ErrTaskCommentDoesNotExist)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrTaskCommentDoesNotExist) Error() string {
|
|
return fmt.Sprintf("Task comment does not exist [ID: %d, TaskID: %d]", err.ID, err.TaskID)
|
|
}
|
|
|
|
// ErrCodeTaskCommentDoesNotExist holds the unique world-error code of this error
|
|
const ErrCodeTaskCommentDoesNotExist = 4015
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrTaskCommentDoesNotExist) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusNotFound,
|
|
Code: ErrCodeTaskCommentDoesNotExist,
|
|
Message: "This task comment does not exist",
|
|
}
|
|
}
|
|
|
|
// ErrInvalidTaskField represents an error where the provided task field is invalid
|
|
type ErrInvalidTaskField struct {
|
|
TaskField string
|
|
}
|
|
|
|
// IsErrInvalidTaskField checks if an error is ErrInvalidTaskField.
|
|
func IsErrInvalidTaskField(err error) bool {
|
|
_, ok := err.(ErrInvalidTaskField)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrInvalidTaskField) Error() string {
|
|
return fmt.Sprintf("Task Field is invalid [TaskField: %s]", err.TaskField)
|
|
}
|
|
|
|
// ErrCodeInvalidTaskField holds the unique world-error code of this error
|
|
const ErrCodeInvalidTaskField = 4016
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrInvalidTaskField) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeInvalidTaskField,
|
|
Message: fmt.Sprintf("The task field '%s' is invalid.", err.TaskField),
|
|
}
|
|
}
|
|
|
|
// ErrInvalidTaskFilterComparator represents an error where the provided task field is invalid
|
|
type ErrInvalidTaskFilterComparator struct {
|
|
Comparator taskFilterComparator
|
|
}
|
|
|
|
// IsErrInvalidTaskFilterComparator checks if an error is ErrInvalidTaskFilterComparator.
|
|
func IsErrInvalidTaskFilterComparator(err error) bool {
|
|
_, ok := err.(ErrInvalidTaskFilterComparator)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrInvalidTaskFilterComparator) Error() string {
|
|
return fmt.Sprintf("Task filter comparator is invalid [Comparator: %s]", err.Comparator)
|
|
}
|
|
|
|
// ErrCodeInvalidTaskFilterComparator holds the unique world-error code of this error
|
|
const ErrCodeInvalidTaskFilterComparator = 4017
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrInvalidTaskFilterComparator) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeInvalidTaskFilterComparator,
|
|
Message: fmt.Sprintf("The task filter comparator '%s' is invalid.", err.Comparator),
|
|
}
|
|
}
|
|
|
|
// ErrInvalidTaskFilterConcatinator represents an error where the provided task field is invalid
|
|
type ErrInvalidTaskFilterConcatinator struct {
|
|
Concatinator taskFilterConcatinator
|
|
}
|
|
|
|
// IsErrInvalidTaskFilterConcatinator checks if an error is ErrInvalidTaskFilterConcatinator.
|
|
func IsErrInvalidTaskFilterConcatinator(err error) bool {
|
|
_, ok := err.(ErrInvalidTaskFilterConcatinator)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrInvalidTaskFilterConcatinator) Error() string {
|
|
return fmt.Sprintf("Task filter concatinator is invalid [Concatinator: %s]", err.Concatinator)
|
|
}
|
|
|
|
// ErrCodeInvalidTaskFilterConcatinator holds the unique world-error code of this error
|
|
const ErrCodeInvalidTaskFilterConcatinator = 4018
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrInvalidTaskFilterConcatinator) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeInvalidTaskFilterConcatinator,
|
|
Message: fmt.Sprintf("The task filter concatinator '%s' is invalid.", err.Concatinator),
|
|
}
|
|
}
|
|
|
|
// ErrInvalidTaskFilterValue represents an error where the provided task filter value is invalid
|
|
type ErrInvalidTaskFilterValue struct {
|
|
Value interface{}
|
|
Field string
|
|
}
|
|
|
|
// IsErrInvalidTaskFilterValue checks if an error is ErrInvalidTaskFilterValue.
|
|
func IsErrInvalidTaskFilterValue(err error) bool {
|
|
_, ok := err.(ErrInvalidTaskFilterValue)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrInvalidTaskFilterValue) Error() string {
|
|
return fmt.Sprintf("Task filter value is invalid [Value: %v, Field: %s]", err.Value, err.Field)
|
|
}
|
|
|
|
// ErrCodeInvalidTaskFilterValue holds the unique world-error code of this error
|
|
const ErrCodeInvalidTaskFilterValue = 4019
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrInvalidTaskFilterValue) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeInvalidTaskFilterValue,
|
|
Message: fmt.Sprintf("The task filter value '%s' for field '%s' is invalid.", err.Value, err.Field),
|
|
}
|
|
}
|
|
|
|
// ErrAttachmentDoesNotBelongToTask represents an error where the provided task cover attachment does not belong to the same task
|
|
type ErrAttachmentDoesNotBelongToTask struct {
|
|
TaskID int64
|
|
AttachmentID int64
|
|
}
|
|
|
|
// IsErrAttachmentAndCoverMustBelongToTheSameTask checks if an error is ErrAttachmentDoesNotBelongToTask.
|
|
func IsErrAttachmentAndCoverMustBelongToTheSameTask(err error) bool {
|
|
_, ok := err.(ErrAttachmentDoesNotBelongToTask)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrAttachmentDoesNotBelongToTask) Error() string {
|
|
return fmt.Sprintf("Task attachment and cover image do not belong to the same task [TaskID: %d, AttachmentID: %d]", err.TaskID, err.AttachmentID)
|
|
}
|
|
|
|
// ErrCodeAttachmentDoesNotBelongToTask holds the unique world-error code of this error
|
|
const ErrCodeAttachmentDoesNotBelongToTask = 4020
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrAttachmentDoesNotBelongToTask) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeAttachmentDoesNotBelongToTask,
|
|
Message: "This attachment does not belong to that task.",
|
|
}
|
|
}
|
|
|
|
// ErrUserAlreadyAssigned represents an error where the user is already assigned to this task
|
|
type ErrUserAlreadyAssigned struct {
|
|
TaskID int64
|
|
UserID int64
|
|
}
|
|
|
|
// IsErrUserAlreadyAssigned checks if an error is ErrUserAlreadyAssigned.
|
|
func IsErrUserAlreadyAssigned(err error) bool {
|
|
_, ok := err.(ErrUserAlreadyAssigned)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrUserAlreadyAssigned) Error() string {
|
|
return fmt.Sprintf("User is already assigned to task [TaskID: %d, ID: %d]", err.TaskID, err.UserID)
|
|
}
|
|
|
|
// ErrCodeUserAlreadyAssigned holds the unique world-error code of this error
|
|
const ErrCodeUserAlreadyAssigned = 4021
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrUserAlreadyAssigned) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeUserAlreadyAssigned,
|
|
Message: "This user is already assigned to that task.",
|
|
}
|
|
}
|
|
|
|
// ErrReminderRelativeToMissing represents an error where a task has a relative reminder without reference date
|
|
type ErrReminderRelativeToMissing struct {
|
|
TaskID int64
|
|
}
|
|
|
|
// IsErrReminderRelativeToMissing checks if an error is ErrReminderRelativeToMissing.
|
|
func IsErrReminderRelativeToMissing(err error) bool {
|
|
_, ok := err.(ErrReminderRelativeToMissing)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrReminderRelativeToMissing) Error() string {
|
|
return fmt.Sprintf("Task [TaskID: %v] has a relative reminder without relative_to", err.TaskID)
|
|
}
|
|
|
|
// ErrCodeRelationDoesNotExist holds the unique world-error code of this error
|
|
const ErrCodeReminderRelativeToMissing = 4022
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrReminderRelativeToMissing) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeReminderRelativeToMissing,
|
|
Message: "Please provide what the reminder date is relative to",
|
|
}
|
|
}
|
|
|
|
// ErrTaskRelationCycle represents an error where the user tries to create an already existing relation
|
|
type ErrTaskRelationCycle struct {
|
|
Kind RelationKind
|
|
TaskID int64
|
|
OtherTaskID int64
|
|
}
|
|
|
|
// IsErrTaskRelationCycle checks if an error is ErrTaskRelationCycle.
|
|
func IsErrTaskRelationCycle(err error) bool {
|
|
_, ok := err.(ErrTaskRelationCycle)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrTaskRelationCycle) Error() string {
|
|
return fmt.Sprintf("Task relation cycle detectetd [TaskID: %v, OtherTaskID: %v, Kind: %v]", err.TaskID, err.OtherTaskID, err.Kind)
|
|
}
|
|
|
|
// ErrCodeTaskRelationCycle holds the unique world-error code of this error
|
|
const ErrCodeTaskRelationCycle = 4023
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrTaskRelationCycle) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusConflict,
|
|
Code: ErrCodeTaskRelationCycle,
|
|
Message: "This task relation would create a cycle.",
|
|
}
|
|
}
|
|
|
|
// ErrInvalidFilterExpression represents an error where the task filter expression was invalid
|
|
type ErrInvalidFilterExpression struct {
|
|
Expression string
|
|
ExpressionError error
|
|
}
|
|
|
|
// IsErrInvalidFilterExpression checks if an error is ErrInvalidFilterExpression.
|
|
func IsErrInvalidFilterExpression(err error) bool {
|
|
_, ok := err.(ErrInvalidFilterExpression)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrInvalidFilterExpression) Error() string {
|
|
return fmt.Sprintf("Task filter expression '%s' is invalid [ExpressionError: %v]", err.Expression, err.ExpressionError)
|
|
}
|
|
|
|
// ErrCodeInvalidFilterExpression holds the unique world-error code of this error
|
|
const ErrCodeInvalidFilterExpression = 4024
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrInvalidFilterExpression) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeInvalidFilterExpression,
|
|
Message: fmt.Sprintf("The filter expression '%s' is invalid: %v", err.Expression, err.ExpressionError),
|
|
}
|
|
}
|
|
|
|
// ErrInvalidReactionEntityKind represents an error where the reaction kind is invalid
|
|
type ErrInvalidReactionEntityKind struct {
|
|
Kind string
|
|
}
|
|
|
|
// IsErrInvalidReactionEntityKind checks if an error is ErrInvalidReactionEntityKind.
|
|
func IsErrInvalidReactionEntityKind(err error) bool {
|
|
_, ok := err.(ErrInvalidReactionEntityKind)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrInvalidReactionEntityKind) Error() string {
|
|
return fmt.Sprintf("Reaction kind %s is invalid", err.Kind)
|
|
}
|
|
|
|
// ErrCodeInvalidReactionEntityKind holds the unique world-error code of this error
|
|
const ErrCodeInvalidReactionEntityKind = 4025
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrInvalidReactionEntityKind) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeInvalidReactionEntityKind,
|
|
Message: fmt.Sprintf("The reaction kind '%s' is invalid.", err.Kind),
|
|
}
|
|
}
|
|
|
|
// ErrMustHaveProjectViewToSortByPosition represents an error where no project view id was supplied
|
|
type ErrMustHaveProjectViewToSortByPosition struct{}
|
|
|
|
func (err ErrMustHaveProjectViewToSortByPosition) Error() string {
|
|
return "You must provide a project view ID when sorting by position"
|
|
}
|
|
|
|
// ErrCodeMustHaveProjectViewToSortByPosition holds the unique world-error code of this error
|
|
const ErrCodeMustHaveProjectViewToSortByPosition = 4026
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrMustHaveProjectViewToSortByPosition) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeMustHaveProjectViewToSortByPosition,
|
|
Message: "You must provide a project view ID when sorting by position",
|
|
}
|
|
}
|
|
|
|
// ErrInvalidTaskColumn represents an error where the provided task column is invalid
|
|
type ErrInvalidTaskColumn struct {
|
|
Column string
|
|
}
|
|
|
|
// IsErrInvalidTaskColumn checks if an error is ErrInvalidTaskColumn.
|
|
func IsErrInvalidTaskColumn(err error) bool {
|
|
_, ok := err.(ErrInvalidTaskColumn)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrInvalidTaskColumn) Error() string {
|
|
return fmt.Sprintf("Task column %s is invalid", err.Column)
|
|
}
|
|
|
|
// ErrCodeInvalidTaskColumn holds the unique world-error code of this error
|
|
const ErrCodeInvalidTaskColumn = 4027
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrInvalidTaskColumn) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeInvalidTaskColumn,
|
|
Message: fmt.Sprintf("The task field '%s' is invalid.", err.Column),
|
|
}
|
|
}
|
|
|
|
// ErrNeedsFullRecalculation represents an error where localized position repair cannot proceed
|
|
// and the entire view must be recalculated.
|
|
type ErrNeedsFullRecalculation struct {
|
|
ProjectViewID int64
|
|
}
|
|
|
|
// IsErrNeedsFullRecalculation checks if an error is ErrNeedsFullRecalculation.
|
|
func IsErrNeedsFullRecalculation(err error) bool {
|
|
_, ok := err.(*ErrNeedsFullRecalculation)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrNeedsFullRecalculation) Error() string {
|
|
return fmt.Sprintf("Insufficient spacing for localized repair [ProjectViewID: %d]", err.ProjectViewID)
|
|
}
|
|
|
|
// ErrCodeNeedsFullRecalculation holds the unique world-error code of this error
|
|
const ErrCodeNeedsFullRecalculation = 4028
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrNeedsFullRecalculation) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusInternalServerError,
|
|
Code: ErrCodeNeedsFullRecalculation,
|
|
Message: "Position repair requires full view recalculation.",
|
|
}
|
|
}
|
|
|
|
// ============
|
|
// Team errors
|
|
// ============
|
|
|
|
// ErrTeamNameCannotBeEmpty represents an error where a team name is empty.
|
|
type ErrTeamNameCannotBeEmpty struct {
|
|
TeamID int64
|
|
}
|
|
|
|
// IsErrTeamNameCannotBeEmpty checks if an error is a ErrTeamNameCannotBeEmpty.
|
|
func IsErrTeamNameCannotBeEmpty(err error) bool {
|
|
_, ok := err.(ErrTeamNameCannotBeEmpty)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrTeamNameCannotBeEmpty) Error() string {
|
|
return fmt.Sprintf("Team name cannot be empty [Team ID: %d]", err.TeamID)
|
|
}
|
|
|
|
// ErrCodeTeamNameCannotBeEmpty holds the unique world-error code of this error
|
|
const ErrCodeTeamNameCannotBeEmpty = 6001
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrTeamNameCannotBeEmpty) HTTPError() web.HTTPError {
|
|
return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrCodeTeamNameCannotBeEmpty, Message: "The team name cannot be empty"}
|
|
}
|
|
|
|
type ErrTeamDoesNotExist struct {
|
|
TeamID int64
|
|
}
|
|
|
|
// IsErrTeamDoesNotExist checks if an error is ErrTeamDoesNotExist.
|
|
func IsErrTeamDoesNotExist(err error) bool {
|
|
_, ok := err.(ErrTeamDoesNotExist)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrTeamDoesNotExist) Error() string {
|
|
return fmt.Sprintf("Team does not exist [Team ID: %d]", err.TeamID)
|
|
}
|
|
|
|
// ErrCodeTeamDoesNotExist holds the unique world-error code of this error
|
|
const ErrCodeTeamDoesNotExist = 6002
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrTeamDoesNotExist) HTTPError() web.HTTPError {
|
|
return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "This team does not exist."}
|
|
}
|
|
|
|
// ErrTeamAlreadyHasAccess represents an error where a team already has access to a project
|
|
type ErrTeamAlreadyHasAccess struct {
|
|
TeamID int64
|
|
ID int64
|
|
}
|
|
|
|
// IsErrTeamAlreadyHasAccess checks if an error is ErrTeamAlreadyHasAccess.
|
|
func IsErrTeamAlreadyHasAccess(err error) bool {
|
|
_, ok := err.(ErrTeamAlreadyHasAccess)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrTeamAlreadyHasAccess) Error() string {
|
|
return fmt.Sprintf("Team already has access. [Team ID: %d, ID: %d]", err.TeamID, err.ID)
|
|
}
|
|
|
|
// ErrCodeTeamAlreadyHasAccess holds the unique world-error code of this error
|
|
const ErrCodeTeamAlreadyHasAccess = 6004
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrTeamAlreadyHasAccess) HTTPError() web.HTTPError {
|
|
return web.HTTPError{HTTPCode: http.StatusConflict, Code: ErrCodeTeamAlreadyHasAccess, Message: "This team already has access."}
|
|
}
|
|
|
|
// ErrUserIsMemberOfTeam represents an error where a user is already member of a team.
|
|
type ErrUserIsMemberOfTeam struct {
|
|
TeamID int64
|
|
UserID int64
|
|
}
|
|
|
|
// IsErrUserIsMemberOfTeam checks if an error is ErrUserIsMemberOfTeam.
|
|
func IsErrUserIsMemberOfTeam(err error) bool {
|
|
_, ok := err.(ErrUserIsMemberOfTeam)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrUserIsMemberOfTeam) Error() string {
|
|
return fmt.Sprintf("User is already a member of that team. [Team ID: %d, User ID: %d]", err.TeamID, err.UserID)
|
|
}
|
|
|
|
// ErrCodeUserIsMemberOfTeam holds the unique world-error code of this error
|
|
const ErrCodeUserIsMemberOfTeam = 6005
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrUserIsMemberOfTeam) HTTPError() web.HTTPError {
|
|
return web.HTTPError{HTTPCode: http.StatusConflict, Code: ErrCodeUserIsMemberOfTeam, Message: "This user is already a member of that team."}
|
|
}
|
|
|
|
// ErrCannotDeleteLastTeamMember represents an error where a user wants to delete the last member of a team (probably himself)
|
|
type ErrCannotDeleteLastTeamMember struct {
|
|
TeamID int64
|
|
UserID int64
|
|
}
|
|
|
|
// IsErrCannotDeleteLastTeamMember checks if an error is ErrCannotDeleteLastTeamMember.
|
|
func IsErrCannotDeleteLastTeamMember(err error) bool {
|
|
_, ok := err.(ErrCannotDeleteLastTeamMember)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrCannotDeleteLastTeamMember) Error() string {
|
|
return fmt.Sprintf("Cannot delete last team member. [Team ID: %d, User ID: %d]", err.TeamID, err.UserID)
|
|
}
|
|
|
|
// ErrCodeCannotDeleteLastTeamMember holds the unique world-error code of this error
|
|
const ErrCodeCannotDeleteLastTeamMember = 6006
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrCannotDeleteLastTeamMember) HTTPError() web.HTTPError {
|
|
return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrCodeCannotDeleteLastTeamMember, Message: "You cannot delete the last member of a team."}
|
|
}
|
|
|
|
// ErrTeamDoesNotHaveAccessToProject represents an error, where the Team is not the owner of that Project (used i.e. when deleting a Project)
|
|
type ErrTeamDoesNotHaveAccessToProject struct {
|
|
ProjectID int64
|
|
TeamID int64
|
|
}
|
|
|
|
// IsErrTeamDoesNotHaveAccessToProject checks if an error is a ErrProjectDoesNotExist.
|
|
func IsErrTeamDoesNotHaveAccessToProject(err error) bool {
|
|
_, ok := err.(ErrTeamDoesNotHaveAccessToProject)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrTeamDoesNotHaveAccessToProject) Error() string {
|
|
return fmt.Sprintf("Team does not have access to the project [ProjectID: %d, TeamID: %d]", err.ProjectID, err.TeamID)
|
|
}
|
|
|
|
// ErrCodeTeamDoesNotHaveAccessToProject holds the unique world-error code of this error
|
|
const ErrCodeTeamDoesNotHaveAccessToProject = 6007
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrTeamDoesNotHaveAccessToProject) HTTPError() web.HTTPError {
|
|
return web.HTTPError{HTTPCode: http.StatusForbidden, Code: ErrCodeTeamDoesNotHaveAccessToProject, Message: "This team does not have access to the project."}
|
|
}
|
|
|
|
// ErrExternalTeamDoesNotExist represents an error where a team with specified oidcId property does not exist for a given issuer
|
|
type ErrExternalTeamDoesNotExist struct {
|
|
ExternalID string
|
|
Issuer string
|
|
}
|
|
|
|
// IsErrExternalTeamDoesNotExist checks if an error is ErrExternalTeamDoesNotExist.
|
|
func IsErrExternalTeamDoesNotExist(err error) bool {
|
|
_, ok := err.(ErrExternalTeamDoesNotExist)
|
|
return ok
|
|
}
|
|
|
|
// ErrTeamDoesNotExist represents an error where a team does not exist
|
|
func (err ErrExternalTeamDoesNotExist) Error() string {
|
|
return fmt.Sprintf("No team could be found for the given oidcId and issuer. [OIDC ID : %v] [Issuer: %v] ", err.ExternalID, err.Issuer)
|
|
}
|
|
|
|
// ErrCodeTeamDoesNotExist holds the unique world-error code of this error
|
|
const ErrCodeOIDCTeamDoesNotExist = 6008
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrExternalTeamDoesNotExist) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusNotFound,
|
|
Code: ErrCodeTeamDoesNotExist,
|
|
Message: "No team could be found for the given OIDC ID and issuer.",
|
|
}
|
|
}
|
|
|
|
// ErrOIDCTeamsDoNotExistForUser represents an error where an oidcTeam does not exist for the user
|
|
type ErrOIDCTeamsDoNotExistForUser struct {
|
|
UserID int64
|
|
}
|
|
|
|
// IsErrOIDCTeamsDoNotExistForUser checks if an error is ErrOIDCTeamsDoNotExistForUser.
|
|
func IsErrOIDCTeamsDoNotExistForUser(err error) bool {
|
|
_, ok := err.(ErrOIDCTeamsDoNotExistForUser)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrOIDCTeamsDoNotExistForUser) Error() string {
|
|
return fmt.Sprintf("No teams with property oidcId could be found for user [User ID: %d]", err.UserID)
|
|
}
|
|
|
|
// ErrCodeTeamDoesNotExist holds the unique world-error code of this error
|
|
const ErrCodeOIDCTeamsDoNotExistForUser = 6009
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrOIDCTeamsDoNotExistForUser) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusNotFound,
|
|
Code: ErrCodeOIDCTeamsDoNotExistForUser,
|
|
Message: "No Teams with property oidcId could be found for User.",
|
|
}
|
|
}
|
|
|
|
// ErrCannotRemoveUserFromExternalTeam represents an error where an oidcTeam does not exist for the user
|
|
type ErrCannotRemoveUserFromExternalTeam struct {
|
|
TeamID int64
|
|
}
|
|
|
|
func (err ErrCannotRemoveUserFromExternalTeam) Error() string {
|
|
return fmt.Sprintf("Users cannot be removed from an external team [Team ID: %d]", err.TeamID)
|
|
}
|
|
|
|
const ErrCodeCannotLeaveExternalTeam = 6010
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrCannotRemoveUserFromExternalTeam) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusPreconditionFailed,
|
|
Code: ErrCodeCannotLeaveExternalTeam,
|
|
Message: "Users cannot be removed from an external team.",
|
|
}
|
|
}
|
|
|
|
// ====================
|
|
// User <-> Project errors
|
|
// ====================
|
|
|
|
// ErrUserAlreadyHasAccess represents an error where a user already has access to a project
|
|
type ErrUserAlreadyHasAccess struct {
|
|
UserID int64
|
|
ProjectID int64
|
|
}
|
|
|
|
// IsErrUserAlreadyHasAccess checks if an error is ErrUserAlreadyHasAccess.
|
|
func IsErrUserAlreadyHasAccess(err error) bool {
|
|
_, ok := err.(ErrUserAlreadyHasAccess)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrUserAlreadyHasAccess) Error() string {
|
|
return fmt.Sprintf("User already has access to that project. [User ID: %d, Project ID: %d]", err.UserID, err.ProjectID)
|
|
}
|
|
|
|
// ErrCodeUserAlreadyHasAccess holds the unique world-error code of this error
|
|
const ErrCodeUserAlreadyHasAccess = 7002
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrUserAlreadyHasAccess) HTTPError() web.HTTPError {
|
|
return web.HTTPError{HTTPCode: http.StatusConflict, Code: ErrCodeUserAlreadyHasAccess, Message: "This user already has access to this project."}
|
|
}
|
|
|
|
// ErrUserDoesNotHaveAccessToProject represents an error, where the user is not the owner of that Project (used i.e. when deleting a Project)
|
|
type ErrUserDoesNotHaveAccessToProject struct {
|
|
ProjectID int64
|
|
UserID int64
|
|
}
|
|
|
|
// IsErrUserDoesNotHaveAccessToProject checks if an error is a ErrProjectDoesNotExist.
|
|
func IsErrUserDoesNotHaveAccessToProject(err error) bool {
|
|
_, ok := err.(ErrUserDoesNotHaveAccessToProject)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrUserDoesNotHaveAccessToProject) Error() string {
|
|
return fmt.Sprintf("User does not have access to the project [ProjectID: %d, ID: %d]", err.ProjectID, err.UserID)
|
|
}
|
|
|
|
// ErrCodeUserDoesNotHaveAccessToProject holds the unique world-error code of this error
|
|
const ErrCodeUserDoesNotHaveAccessToProject = 7003
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrUserDoesNotHaveAccessToProject) HTTPError() web.HTTPError {
|
|
return web.HTTPError{HTTPCode: http.StatusForbidden, Code: ErrCodeUserDoesNotHaveAccessToProject, Message: "This user does not have access to the project."}
|
|
}
|
|
|
|
// =============
|
|
// Label errors
|
|
// =============
|
|
|
|
// ErrLabelIsAlreadyOnTask represents an error where a label is already bound to a task
|
|
type ErrLabelIsAlreadyOnTask struct {
|
|
LabelID int64
|
|
TaskID int64
|
|
}
|
|
|
|
// IsErrLabelIsAlreadyOnTask checks if an error is ErrLabelIsAlreadyOnTask.
|
|
func IsErrLabelIsAlreadyOnTask(err error) bool {
|
|
_, ok := err.(ErrLabelIsAlreadyOnTask)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrLabelIsAlreadyOnTask) Error() string {
|
|
return fmt.Sprintf("Label already exists on task [TaskID: %v, LabelID: %v]", err.TaskID, err.LabelID)
|
|
}
|
|
|
|
// ErrCodeLabelIsAlreadyOnTask holds the unique world-error code of this error
|
|
const ErrCodeLabelIsAlreadyOnTask = 8001
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrLabelIsAlreadyOnTask) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeLabelIsAlreadyOnTask,
|
|
Message: "This label already exists on the task.",
|
|
}
|
|
}
|
|
|
|
// ErrLabelDoesNotExist represents an error where a label does not exist
|
|
type ErrLabelDoesNotExist struct {
|
|
LabelID int64
|
|
}
|
|
|
|
// IsErrLabelDoesNotExist checks if an error is ErrLabelDoesNotExist.
|
|
func IsErrLabelDoesNotExist(err error) bool {
|
|
_, ok := err.(ErrLabelDoesNotExist)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrLabelDoesNotExist) Error() string {
|
|
return fmt.Sprintf("Label does not exist [LabelID: %v]", err.LabelID)
|
|
}
|
|
|
|
// ErrCodeLabelDoesNotExist holds the unique world-error code of this error
|
|
const ErrCodeLabelDoesNotExist = 8002
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrLabelDoesNotExist) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusNotFound,
|
|
Code: ErrCodeLabelDoesNotExist,
|
|
Message: "This label does not exist.",
|
|
}
|
|
}
|
|
|
|
// ErrUserHasNoAccessToLabel represents an error where a user does not have the permission to see a label
|
|
type ErrUserHasNoAccessToLabel struct {
|
|
LabelID int64
|
|
UserID int64
|
|
}
|
|
|
|
// IsErrUserHasNoAccessToLabel checks if an error is ErrUserHasNoAccessToLabel.
|
|
func IsErrUserHasNoAccessToLabel(err error) bool {
|
|
_, ok := err.(ErrUserHasNoAccessToLabel)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrUserHasNoAccessToLabel) Error() string {
|
|
return fmt.Sprintf("The user does not have access to this label [LabelID: %v, ID: %v]", err.LabelID, err.UserID)
|
|
}
|
|
|
|
// ErrCodeUserHasNoAccessToLabel holds the unique world-error code of this error
|
|
const ErrCodeUserHasNoAccessToLabel = 8003
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrUserHasNoAccessToLabel) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusForbidden,
|
|
Code: ErrCodeUserHasNoAccessToLabel,
|
|
Message: "You don't have access to this label.",
|
|
}
|
|
}
|
|
|
|
// ========
|
|
// Permissions
|
|
// ========
|
|
|
|
// ErrInvalidPermission represents an error where a permission is invalid
|
|
type ErrInvalidPermission struct {
|
|
Permission Permission
|
|
}
|
|
|
|
// IsErrInvalidPermission checks if an error is ErrInvalidPermission.
|
|
func IsErrInvalidPermission(err error) bool {
|
|
_, ok := err.(ErrInvalidPermission)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrInvalidPermission) Error() string {
|
|
return fmt.Sprintf("Permission invalid [Permission: %d]", err.Permission)
|
|
}
|
|
|
|
// ErrCodeInvalidRight holds the unique world-error code of this error
|
|
const ErrCodeInvalidRight = 9001
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrInvalidPermission) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeInvalidRight,
|
|
Message: "The permission is invalid.",
|
|
}
|
|
}
|
|
|
|
// ========
|
|
// Kanban
|
|
// ========
|
|
|
|
// ErrBucketDoesNotExist represents an error where a kanban bucket does not exist
|
|
type ErrBucketDoesNotExist struct {
|
|
BucketID int64
|
|
}
|
|
|
|
// IsErrBucketDoesNotExist checks if an error is ErrBucketDoesNotExist.
|
|
func IsErrBucketDoesNotExist(err error) bool {
|
|
_, ok := err.(ErrBucketDoesNotExist)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrBucketDoesNotExist) Error() string {
|
|
return fmt.Sprintf("Bucket does not exist [BucketID: %d]", err.BucketID)
|
|
}
|
|
|
|
// ErrCodeBucketDoesNotExist holds the unique world-error code of this error
|
|
const ErrCodeBucketDoesNotExist = 10001
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrBucketDoesNotExist) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusNotFound,
|
|
Code: ErrCodeBucketDoesNotExist,
|
|
Message: "This bucket does not exist.",
|
|
}
|
|
}
|
|
|
|
// ErrBucketDoesNotBelongToProjectView represents an error where a kanban bucket does not belong to a project
|
|
type ErrBucketDoesNotBelongToProjectView struct {
|
|
BucketID int64
|
|
ProjectViewID int64
|
|
}
|
|
|
|
// IsErrBucketDoesNotBelongToProject checks if an error is ErrBucketDoesNotBelongToProjectView.
|
|
func IsErrBucketDoesNotBelongToProject(err error) bool {
|
|
_, ok := err.(ErrBucketDoesNotBelongToProjectView)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrBucketDoesNotBelongToProjectView) Error() string {
|
|
return fmt.Sprintf("Bucket does not not belong to project view [BucketID: %d, ProjectViewID: %d]", err.BucketID, err.ProjectViewID)
|
|
}
|
|
|
|
// ErrCodeBucketDoesNotBelongToProject holds the unique world-error code of this error
|
|
const ErrCodeBucketDoesNotBelongToProject = 10002
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrBucketDoesNotBelongToProjectView) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeBucketDoesNotBelongToProject,
|
|
Message: "This bucket does not belong to that project.",
|
|
}
|
|
}
|
|
|
|
// ErrCannotRemoveLastBucket represents an error where a kanban bucket is the last on a project and thus cannot be removed.
|
|
type ErrCannotRemoveLastBucket struct {
|
|
BucketID int64
|
|
ProjectViewID int64
|
|
}
|
|
|
|
// IsErrCannotRemoveLastBucket checks if an error is ErrCannotRemoveLastBucket.
|
|
func IsErrCannotRemoveLastBucket(err error) bool {
|
|
_, ok := err.(ErrCannotRemoveLastBucket)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrCannotRemoveLastBucket) Error() string {
|
|
return fmt.Sprintf("Cannot remove last bucket of project view [BucketID: %d, ProjectViewID: %d]", err.BucketID, err.ProjectViewID)
|
|
}
|
|
|
|
// ErrCodeCannotRemoveLastBucket holds the unique world-error code of this error
|
|
const ErrCodeCannotRemoveLastBucket = 10003
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrCannotRemoveLastBucket) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusPreconditionFailed,
|
|
Code: ErrCodeCannotRemoveLastBucket,
|
|
Message: "You cannot remove the last bucket on this project view.",
|
|
}
|
|
}
|
|
|
|
// ErrBucketLimitExceeded represents an error where a task is being created or moved to a bucket which has its limit already exceeded.
|
|
type ErrBucketLimitExceeded struct {
|
|
BucketID int64
|
|
Limit int64
|
|
TaskID int64 // may be 0
|
|
}
|
|
|
|
// IsErrBucketLimitExceeded checks if an error is ErrBucketLimitExceeded.
|
|
func IsErrBucketLimitExceeded(err error) bool {
|
|
_, ok := err.(ErrBucketLimitExceeded)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrBucketLimitExceeded) Error() string {
|
|
return fmt.Sprintf("Cannot add a task to this bucket because it would exceed the limit [BucketID: %d, Limit: %d, TaskID: %d]", err.BucketID, err.Limit, err.TaskID)
|
|
}
|
|
|
|
// ErrCodeBucketLimitExceeded holds the unique world-error code of this error
|
|
const ErrCodeBucketLimitExceeded = 10004
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrBucketLimitExceeded) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusPreconditionFailed,
|
|
Code: ErrCodeBucketLimitExceeded,
|
|
Message: "You cannot add the task to this bucket as it already exceeded the limit of tasks it can hold.",
|
|
}
|
|
}
|
|
|
|
// ErrOnlyOneDoneBucketPerProject represents an error where a bucket is set to the done bucket but one already exists for its project.
|
|
type ErrOnlyOneDoneBucketPerProject struct {
|
|
BucketID int64
|
|
ProjectID int64
|
|
DoneBucketID int64
|
|
}
|
|
|
|
// IsErrOnlyOneDoneBucketPerProject checks if an error is ErrBucketLimitExceeded.
|
|
func IsErrOnlyOneDoneBucketPerProject(err error) bool {
|
|
_, ok := err.(*ErrOnlyOneDoneBucketPerProject)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrOnlyOneDoneBucketPerProject) Error() string {
|
|
return fmt.Sprintf("There can be only one done bucket per project [BucketID: %d, ProjectID: %d]", err.BucketID, err.ProjectID)
|
|
}
|
|
|
|
// ErrCodeOnlyOneDoneBucketPerProject holds the unique world-error code of this error
|
|
const ErrCodeOnlyOneDoneBucketPerProject = 10005
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrOnlyOneDoneBucketPerProject) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusPreconditionFailed,
|
|
Code: ErrCodeOnlyOneDoneBucketPerProject,
|
|
Message: "There can be only one done bucket per project.",
|
|
}
|
|
}
|
|
|
|
// ErrTaskAlreadyExistsInBucket represents an error where a task already exists in a bucket for a project view
|
|
type ErrTaskAlreadyExistsInBucket struct {
|
|
TaskID int64
|
|
ProjectViewID int64
|
|
}
|
|
|
|
// IsErrTaskAlreadyExistsInBucket checks if an error is ErrTaskAlreadyExistsInBucket.
|
|
func IsErrTaskAlreadyExistsInBucket(err error) bool {
|
|
_, ok := err.(ErrTaskAlreadyExistsInBucket)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrTaskAlreadyExistsInBucket) Error() string {
|
|
return fmt.Sprintf("Task already exists in a bucket for this project view [TaskID: %d, ProjectViewID: %d]", err.TaskID, err.ProjectViewID)
|
|
}
|
|
|
|
// ErrCodeTaskAlreadyExistsInBucket holds the unique world-error code of this error
|
|
const ErrCodeTaskAlreadyExistsInBucket = 10006
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrTaskAlreadyExistsInBucket) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeTaskAlreadyExistsInBucket,
|
|
Message: "This task already exists in a bucket for this project view.",
|
|
}
|
|
}
|
|
|
|
// =============
|
|
// Saved Filters
|
|
// =============
|
|
|
|
// ErrSavedFilterDoesNotExist represents an error where a kanban bucket does not exist
|
|
type ErrSavedFilterDoesNotExist struct {
|
|
SavedFilterID int64
|
|
}
|
|
|
|
// IsErrSavedFilterDoesNotExist checks if an error is ErrSavedFilterDoesNotExist.
|
|
func IsErrSavedFilterDoesNotExist(err error) bool {
|
|
_, ok := err.(ErrSavedFilterDoesNotExist)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrSavedFilterDoesNotExist) Error() string {
|
|
return fmt.Sprintf("Saved filter does not exist [SavedFilterID: %d]", err.SavedFilterID)
|
|
}
|
|
|
|
// ErrCodeSavedFilterDoesNotExist holds the unique world-error code of this error
|
|
const ErrCodeSavedFilterDoesNotExist = 11001
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrSavedFilterDoesNotExist) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusNotFound,
|
|
Code: ErrCodeSavedFilterDoesNotExist,
|
|
Message: "This saved filter does not exist.",
|
|
}
|
|
}
|
|
|
|
// ErrSavedFilterNotAvailableForLinkShare represents an error where a kanban bucket does not exist
|
|
type ErrSavedFilterNotAvailableForLinkShare struct {
|
|
SavedFilterID int64
|
|
LinkShareID int64
|
|
}
|
|
|
|
// IsErrSavedFilterNotAvailableForLinkShare checks if an error is ErrSavedFilterNotAvailableForLinkShare.
|
|
func IsErrSavedFilterNotAvailableForLinkShare(err error) bool {
|
|
_, ok := err.(ErrSavedFilterNotAvailableForLinkShare)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrSavedFilterNotAvailableForLinkShare) Error() string {
|
|
return fmt.Sprintf("Saved filters are not available for link shares [SavedFilterID: %d, LinkShareID: %d]", err.SavedFilterID, err.LinkShareID)
|
|
}
|
|
|
|
// ErrCodeSavedFilterNotAvailableForLinkShare holds the unique world-error code of this error
|
|
const ErrCodeSavedFilterNotAvailableForLinkShare = 11002
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrSavedFilterNotAvailableForLinkShare) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusPreconditionFailed,
|
|
Code: ErrCodeSavedFilterNotAvailableForLinkShare,
|
|
Message: "Saved filters are not available for link shares.",
|
|
}
|
|
}
|
|
|
|
// =============
|
|
// Subscriptions
|
|
// =============
|
|
|
|
// ErrUnknownSubscriptionEntityType represents an error where a subscription entity type is unknown
|
|
type ErrUnknownSubscriptionEntityType struct {
|
|
EntityType SubscriptionEntityType
|
|
}
|
|
|
|
// IsErrUnknownSubscriptionEntityType checks if an error is ErrUnknownSubscriptionEntityType.
|
|
func IsErrUnknownSubscriptionEntityType(err error) bool {
|
|
_, ok := err.(*ErrUnknownSubscriptionEntityType)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrUnknownSubscriptionEntityType) Error() string {
|
|
return fmt.Sprintf("Subscription entity type is unknown [EntityType: %d]", err.EntityType)
|
|
}
|
|
|
|
// ErrCodeUnknownSubscriptionEntityType holds the unique world-error code of this error
|
|
const ErrCodeUnknownSubscriptionEntityType = 12001
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrUnknownSubscriptionEntityType) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusPreconditionFailed,
|
|
Code: ErrCodeUnknownSubscriptionEntityType,
|
|
Message: "The subscription entity type is invalid.",
|
|
}
|
|
}
|
|
|
|
// ErrSubscriptionAlreadyExists represents an error where a subscription entity already exists
|
|
type ErrSubscriptionAlreadyExists struct {
|
|
EntityID int64
|
|
EntityType SubscriptionEntityType
|
|
UserID int64
|
|
}
|
|
|
|
// IsErrSubscriptionAlreadyExists checks if an error is ErrSubscriptionAlreadyExists.
|
|
func IsErrSubscriptionAlreadyExists(err error) bool {
|
|
_, ok := err.(*ErrSubscriptionAlreadyExists)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrSubscriptionAlreadyExists) Error() string {
|
|
return fmt.Sprintf("Subscription for this (entity_id, entity_type, user_id) already exists [EntityType: %d, EntityID: %d, UserID: %d]", err.EntityType, err.EntityID, err.UserID)
|
|
}
|
|
|
|
// ErrCodeSubscriptionAlreadyExists holds the unique world-error code of this error
|
|
const ErrCodeSubscriptionAlreadyExists = 12002
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrSubscriptionAlreadyExists) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusPreconditionFailed,
|
|
Code: ErrCodeSubscriptionAlreadyExists,
|
|
Message: "You're already subscribed.",
|
|
}
|
|
}
|
|
|
|
// ErrMustProvideUser represents an error where you need to provide a user to fetch subscriptions
|
|
type ErrMustProvideUser struct {
|
|
}
|
|
|
|
// IsErrMustProvideUser checks if an error is ErrMustProvideUser.
|
|
func IsErrMustProvideUser(err error) bool {
|
|
_, ok := err.(*ErrMustProvideUser)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrMustProvideUser) Error() string {
|
|
return "no user provided while fetching subscriptions"
|
|
}
|
|
|
|
// ErrCodeMustProvideUser holds the unique world-error code of this error
|
|
const ErrCodeMustProvideUser = 12003
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrMustProvideUser) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusPreconditionFailed,
|
|
Code: ErrCodeMustProvideUser,
|
|
Message: "You must provide a user to fetch subscriptions",
|
|
}
|
|
}
|
|
|
|
// =================
|
|
// Link Share errors
|
|
// =================
|
|
|
|
// ErrLinkSharePasswordRequired represents an error where a link share authentication requires a password and none was provided
|
|
type ErrLinkSharePasswordRequired struct {
|
|
ShareID int64
|
|
}
|
|
|
|
// IsErrLinkSharePasswordRequired checks if an error is ErrLinkSharePasswordRequired.
|
|
func IsErrLinkSharePasswordRequired(err error) bool {
|
|
_, ok := err.(*ErrLinkSharePasswordRequired)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrLinkSharePasswordRequired) Error() string {
|
|
return fmt.Sprintf("Link Share requires a password for authentication [ShareID: %d]", err.ShareID)
|
|
}
|
|
|
|
// ErrCodeLinkSharePasswordRequired holds the unique world-error code of this error
|
|
const ErrCodeLinkSharePasswordRequired = 13001
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrLinkSharePasswordRequired) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusPreconditionFailed,
|
|
Code: ErrCodeLinkSharePasswordRequired,
|
|
Message: "This link share requires a password for authentication, but none was provided.",
|
|
}
|
|
}
|
|
|
|
// ErrLinkSharePasswordInvalid represents an error where a subscription entity type is unknown
|
|
type ErrLinkSharePasswordInvalid struct {
|
|
ShareID int64
|
|
}
|
|
|
|
// IsErrLinkSharePasswordInvalid checks if an error is ErrLinkSharePasswordInvalid.
|
|
func IsErrLinkSharePasswordInvalid(err error) bool {
|
|
_, ok := err.(*ErrLinkSharePasswordInvalid)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrLinkSharePasswordInvalid) Error() string {
|
|
return fmt.Sprintf("Provided Link Share password did not match the saved one [ShareID: %d]", err.ShareID)
|
|
}
|
|
|
|
// ErrCodeLinkSharePasswordInvalid holds the unique world-error code of this error
|
|
const ErrCodeLinkSharePasswordInvalid = 13002
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrLinkSharePasswordInvalid) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusForbidden,
|
|
Code: ErrCodeLinkSharePasswordInvalid,
|
|
Message: "The provided link share password is invalid.",
|
|
}
|
|
}
|
|
|
|
// ErrLinkShareTokenInvalid represents an error where a link share token is invalid
|
|
type ErrLinkShareTokenInvalid struct {
|
|
}
|
|
|
|
// IsErrLinkShareTokenInvalid checks if an error is ErrLinkShareTokenInvalid.
|
|
func IsErrLinkShareTokenInvalid(err error) bool {
|
|
_, ok := err.(*ErrLinkShareTokenInvalid)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrLinkShareTokenInvalid) Error() string {
|
|
return "Provided Link Share Token is invalid"
|
|
}
|
|
|
|
// ErrCodeLinkShareTokenInvalid holds the unique world-error code of this error
|
|
const ErrCodeLinkShareTokenInvalid = 13003
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrLinkShareTokenInvalid) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeLinkShareTokenInvalid,
|
|
Message: "The provided link share token is invalid.",
|
|
}
|
|
}
|
|
|
|
// ================
|
|
// API Token Errors
|
|
// ================
|
|
|
|
// ErrAPITokenInvalid represents an error where an api token is invalid
|
|
type ErrAPITokenInvalid struct {
|
|
}
|
|
|
|
// IsErrAPITokenInvalid checks if an error is ErrAPITokenInvalid.
|
|
func IsErrAPITokenInvalid(err error) bool {
|
|
_, ok := err.(*ErrAPITokenInvalid)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrAPITokenInvalid) Error() string {
|
|
return "Provided API token is invalid"
|
|
}
|
|
|
|
// ErrCodeAPITokenInvalid holds the unique world-error code of this error
|
|
const ErrCodeAPITokenInvalid = 14001
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrAPITokenInvalid) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeAPITokenInvalid,
|
|
Message: "The provided api token is invalid.",
|
|
}
|
|
}
|
|
|
|
// ErrInvalidAPITokenPermission represents an error where an api token is invalid
|
|
type ErrInvalidAPITokenPermission struct {
|
|
Group string
|
|
Permission string
|
|
}
|
|
|
|
// IsErrInvalidAPITokenPermission checks if an error is ErrInvalidAPITokenPermission.
|
|
func IsErrInvalidAPITokenPermission(err error) bool {
|
|
_, ok := err.(*ErrInvalidAPITokenPermission)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrInvalidAPITokenPermission) Error() string {
|
|
return fmt.Sprintf("API token permission %s of group %s is invalid", err.Permission, err.Group)
|
|
}
|
|
|
|
// ErrCodeInvalidAPITokenPermission holds the unique world-error code of this error
|
|
const ErrCodeInvalidAPITokenPermission = 14002
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrInvalidAPITokenPermission) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeInvalidAPITokenPermission,
|
|
Message: fmt.Sprintf("The permission %s of group %s is invalid.", err.Permission, err.Group),
|
|
I18nParams: map[string]string{"permission": err.Permission, "group": err.Group},
|
|
}
|
|
}
|
|
|
|
// OIDC errors
|
|
const ErrCodeOpenIDError = 15001
|
|
|
|
type ErrOpenIDBadRequest struct {
|
|
Message string
|
|
}
|
|
|
|
func (err *ErrOpenIDBadRequest) Error() string {
|
|
return err.Message
|
|
}
|
|
|
|
func (err *ErrOpenIDBadRequest) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeOpenIDError,
|
|
Message: err.Message,
|
|
}
|
|
}
|
|
|
|
type ErrOpenIDBadRequestWithDetails struct {
|
|
Message string
|
|
Details interface{}
|
|
}
|
|
|
|
func (err *ErrOpenIDBadRequestWithDetails) Error() string {
|
|
return err.Message
|
|
}
|
|
|
|
// ==============
|
|
// Session Errors
|
|
// ==============
|
|
|
|
// ErrSessionNotFound represents an error where a session was not found
|
|
type ErrSessionNotFound struct{}
|
|
|
|
// IsErrSessionNotFound checks if an error is ErrSessionNotFound.
|
|
func IsErrSessionNotFound(err error) bool {
|
|
_, ok := err.(*ErrSessionNotFound)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrSessionNotFound) Error() string {
|
|
return "Session not found"
|
|
}
|
|
|
|
// ErrCodeSessionNotFound holds the unique world-error code of this error
|
|
const ErrCodeSessionNotFound = 16001
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrSessionNotFound) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusNotFound,
|
|
Code: ErrCodeSessionNotFound,
|
|
Message: "The session does not exist.",
|
|
}
|
|
}
|
|
|
|
// ====================
|
|
// OAuth Server Errors
|
|
// ====================
|
|
|
|
// ErrOAuthClientNotFound represents an error where the OAuth client ID is not recognized.
|
|
type ErrOAuthClientNotFound struct{}
|
|
|
|
// IsErrOAuthClientNotFound checks if an error is ErrOAuthClientNotFound.
|
|
func IsErrOAuthClientNotFound(err error) bool {
|
|
_, ok := err.(*ErrOAuthClientNotFound)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrOAuthClientNotFound) Error() string {
|
|
return "OAuth client not found"
|
|
}
|
|
|
|
// ErrCodeOAuthClientNotFound holds the unique world-error code of this error
|
|
const ErrCodeOAuthClientNotFound = 17001
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrOAuthClientNotFound) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeOAuthClientNotFound,
|
|
Message: "The OAuth client ID is not recognized.",
|
|
}
|
|
}
|
|
|
|
// ErrOAuthInvalidRedirectURI represents an error where the redirect URI is not allowed.
|
|
type ErrOAuthInvalidRedirectURI struct{}
|
|
|
|
// IsErrOAuthInvalidRedirectURI checks if an error is ErrOAuthInvalidRedirectURI.
|
|
func IsErrOAuthInvalidRedirectURI(err error) bool {
|
|
_, ok := err.(*ErrOAuthInvalidRedirectURI)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrOAuthInvalidRedirectURI) Error() string {
|
|
return "Invalid redirect URI"
|
|
}
|
|
|
|
// ErrCodeOAuthInvalidRedirectURI holds the unique world-error code of this error
|
|
const ErrCodeOAuthInvalidRedirectURI = 17002
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrOAuthInvalidRedirectURI) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeOAuthInvalidRedirectURI,
|
|
Message: "The redirect URI is not allowed for this client.",
|
|
}
|
|
}
|
|
|
|
// ErrOAuthMissingPKCE represents an error where PKCE parameters are missing or invalid.
|
|
type ErrOAuthMissingPKCE struct{}
|
|
|
|
// IsErrOAuthMissingPKCE checks if an error is ErrOAuthMissingPKCE.
|
|
func IsErrOAuthMissingPKCE(err error) bool {
|
|
_, ok := err.(*ErrOAuthMissingPKCE)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrOAuthMissingPKCE) Error() string {
|
|
return "PKCE is required"
|
|
}
|
|
|
|
// ErrCodeOAuthMissingPKCE holds the unique world-error code of this error
|
|
const ErrCodeOAuthMissingPKCE = 17003
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrOAuthMissingPKCE) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeOAuthMissingPKCE,
|
|
Message: "PKCE (code_challenge with S256 method) is required.",
|
|
}
|
|
}
|
|
|
|
// ErrOAuthCodeInvalid represents an error where the authorization code is invalid or already used.
|
|
type ErrOAuthCodeInvalid struct{}
|
|
|
|
// IsErrOAuthCodeInvalid checks if an error is ErrOAuthCodeInvalid.
|
|
func IsErrOAuthCodeInvalid(err error) bool {
|
|
_, ok := err.(*ErrOAuthCodeInvalid)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrOAuthCodeInvalid) Error() string {
|
|
return "Invalid authorization code"
|
|
}
|
|
|
|
// ErrCodeOAuthCodeInvalid holds the unique world-error code of this error
|
|
const ErrCodeOAuthCodeInvalid = 17004
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrOAuthCodeInvalid) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeOAuthCodeInvalid,
|
|
Message: "The authorization code is invalid or has already been used.",
|
|
}
|
|
}
|
|
|
|
// ErrOAuthCodeExpired represents an error where the authorization code has expired.
|
|
type ErrOAuthCodeExpired struct{}
|
|
|
|
// IsErrOAuthCodeExpired checks if an error is ErrOAuthCodeExpired.
|
|
func IsErrOAuthCodeExpired(err error) bool {
|
|
_, ok := err.(*ErrOAuthCodeExpired)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrOAuthCodeExpired) Error() string {
|
|
return "Authorization code expired"
|
|
}
|
|
|
|
// ErrCodeOAuthCodeExpired holds the unique world-error code of this error
|
|
const ErrCodeOAuthCodeExpired = 17005
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrOAuthCodeExpired) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeOAuthCodeExpired,
|
|
Message: "The authorization code has expired.",
|
|
}
|
|
}
|
|
|
|
// ErrOAuthPKCEVerifyFailed represents an error where the PKCE code_verifier does not match.
|
|
type ErrOAuthPKCEVerifyFailed struct{}
|
|
|
|
// IsErrOAuthPKCEVerifyFailed checks if an error is ErrOAuthPKCEVerifyFailed.
|
|
func IsErrOAuthPKCEVerifyFailed(err error) bool {
|
|
_, ok := err.(*ErrOAuthPKCEVerifyFailed)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrOAuthPKCEVerifyFailed) Error() string {
|
|
return "PKCE verification failed"
|
|
}
|
|
|
|
// ErrCodeOAuthPKCEVerifyFailed holds the unique world-error code of this error
|
|
const ErrCodeOAuthPKCEVerifyFailed = 17006
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrOAuthPKCEVerifyFailed) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeOAuthPKCEVerifyFailed,
|
|
Message: "The code_verifier does not match the code_challenge.",
|
|
}
|
|
}
|
|
|
|
// ErrOAuthInvalidGrantType represents an error where the grant_type is not supported.
|
|
type ErrOAuthInvalidGrantType struct{}
|
|
|
|
// IsErrOAuthInvalidGrantType checks if an error is ErrOAuthInvalidGrantType.
|
|
func IsErrOAuthInvalidGrantType(err error) bool {
|
|
_, ok := err.(*ErrOAuthInvalidGrantType)
|
|
return ok
|
|
}
|
|
|
|
func (err *ErrOAuthInvalidGrantType) Error() string {
|
|
return "Invalid grant type"
|
|
}
|
|
|
|
// ErrCodeOAuthInvalidGrantType holds the unique world-error code of this error
|
|
const ErrCodeOAuthInvalidGrantType = 17007
|
|
|
|
// HTTPError holds the http error description
|
|
func (err *ErrOAuthInvalidGrantType) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeOAuthInvalidGrantType,
|
|
Message: "The grant_type is not supported. Use 'authorization_code' or 'refresh_token'.",
|
|
}
|
|
}
|
|
|
|
// ====================
|
|
// Time Tracking Errors
|
|
// ====================
|
|
|
|
// ErrTimeEntryDoesNotExist represents an error where a time entry does not exist
|
|
type ErrTimeEntryDoesNotExist struct {
|
|
TimeEntryID int64
|
|
}
|
|
|
|
// IsErrTimeEntryDoesNotExist checks if an error is ErrTimeEntryDoesNotExist.
|
|
func IsErrTimeEntryDoesNotExist(err error) bool {
|
|
_, ok := err.(ErrTimeEntryDoesNotExist)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrTimeEntryDoesNotExist) Error() string {
|
|
return fmt.Sprintf("Time entry does not exist [TimeEntryID: %v]", err.TimeEntryID)
|
|
}
|
|
|
|
// ErrCodeTimeEntryDoesNotExist holds the unique world-error code of this error
|
|
const ErrCodeTimeEntryDoesNotExist = 18001
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrTimeEntryDoesNotExist) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusNotFound,
|
|
Code: ErrCodeTimeEntryDoesNotExist,
|
|
Message: "This time entry does not exist.",
|
|
}
|
|
}
|
|
|
|
// ErrTimeEntryInvalidContainer represents an error where a time entry is attached
|
|
// to both a task and a project, or to neither (violating the XOR invariant).
|
|
type ErrTimeEntryInvalidContainer struct {
|
|
TaskID int64
|
|
ProjectID int64
|
|
}
|
|
|
|
// IsErrTimeEntryInvalidContainer checks if an error is ErrTimeEntryInvalidContainer.
|
|
func IsErrTimeEntryInvalidContainer(err error) bool {
|
|
_, ok := err.(ErrTimeEntryInvalidContainer)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrTimeEntryInvalidContainer) Error() string {
|
|
return fmt.Sprintf("Time entry must be attached to exactly one of task or project [TaskID: %v, ProjectID: %v]", err.TaskID, err.ProjectID)
|
|
}
|
|
|
|
// ErrCodeTimeEntryInvalidContainer holds the unique world-error code of this error
|
|
const ErrCodeTimeEntryInvalidContainer = 18002
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrTimeEntryInvalidContainer) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeTimeEntryInvalidContainer,
|
|
Message: "A time entry must be attached to exactly one of a task or a project.",
|
|
}
|
|
}
|
|
|
|
// ErrInvalidTimeEntryFilterField represents an error where a time entry filter references a non-filterable field
|
|
type ErrInvalidTimeEntryFilterField struct {
|
|
Field string
|
|
}
|
|
|
|
// IsErrInvalidTimeEntryFilterField checks if an error is ErrInvalidTimeEntryFilterField.
|
|
func IsErrInvalidTimeEntryFilterField(err error) bool {
|
|
_, ok := err.(ErrInvalidTimeEntryFilterField)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrInvalidTimeEntryFilterField) Error() string {
|
|
return fmt.Sprintf("Time entry filter field is invalid [Field: %s]", err.Field)
|
|
}
|
|
|
|
// ErrCodeInvalidTimeEntryFilterField holds the unique world-error code of this error
|
|
const ErrCodeInvalidTimeEntryFilterField = 18003
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrInvalidTimeEntryFilterField) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeInvalidTimeEntryFilterField,
|
|
Message: fmt.Sprintf("The time entry filter field '%s' is invalid. Filterable fields are user_id, task_id, project_id, start_time and end_time.", err.Field),
|
|
}
|
|
}
|
|
|
|
// ErrInvalidTimeEntryFilterValue represents an error where a time entry filter value cannot be parsed for its field
|
|
type ErrInvalidTimeEntryFilterValue struct {
|
|
Field string
|
|
Value string
|
|
}
|
|
|
|
// IsErrInvalidTimeEntryFilterValue checks if an error is ErrInvalidTimeEntryFilterValue.
|
|
func IsErrInvalidTimeEntryFilterValue(err error) bool {
|
|
_, ok := err.(ErrInvalidTimeEntryFilterValue)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrInvalidTimeEntryFilterValue) Error() string {
|
|
return fmt.Sprintf("Time entry filter value is invalid [Field: %s, Value: %s]", err.Field, err.Value)
|
|
}
|
|
|
|
// ErrCodeInvalidTimeEntryFilterValue holds the unique world-error code of this error
|
|
const ErrCodeInvalidTimeEntryFilterValue = 18004
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrInvalidTimeEntryFilterValue) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeInvalidTimeEntryFilterValue,
|
|
Message: fmt.Sprintf("The value '%s' is not valid for the time entry filter field '%s'.", err.Value, err.Field),
|
|
}
|
|
}
|
|
|
|
// ErrNoRunningTimer represents an error where a user has no running timer to act on
|
|
type ErrNoRunningTimer struct {
|
|
UserID int64
|
|
}
|
|
|
|
// IsErrNoRunningTimer checks if an error is ErrNoRunningTimer.
|
|
func IsErrNoRunningTimer(err error) bool {
|
|
_, ok := err.(ErrNoRunningTimer)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrNoRunningTimer) Error() string {
|
|
return fmt.Sprintf("No running timer [UserID: %d]", err.UserID)
|
|
}
|
|
|
|
// ErrCodeNoRunningTimer holds the unique world-error code of this error
|
|
const ErrCodeNoRunningTimer = 18005
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrNoRunningTimer) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusNotFound,
|
|
Code: ErrCodeNoRunningTimer,
|
|
Message: "You do not have a running timer.",
|
|
}
|
|
}
|
|
|
|
// ErrTimeEntryAlreadyEnded represents an error where an update tries to clear the
|
|
// end time of an entry that has already ended (reopening it as a running timer).
|
|
type ErrTimeEntryAlreadyEnded struct {
|
|
TimeEntryID int64
|
|
}
|
|
|
|
// IsErrTimeEntryAlreadyEnded checks if an error is ErrTimeEntryAlreadyEnded.
|
|
func IsErrTimeEntryAlreadyEnded(err error) bool {
|
|
_, ok := err.(ErrTimeEntryAlreadyEnded)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrTimeEntryAlreadyEnded) Error() string {
|
|
return fmt.Sprintf("Time entry has already ended and cannot be reopened [TimeEntryID: %v]", err.TimeEntryID)
|
|
}
|
|
|
|
// ErrCodeTimeEntryAlreadyEnded holds the unique world-error code of this error
|
|
const ErrCodeTimeEntryAlreadyEnded = 18006
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrTimeEntryAlreadyEnded) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeTimeEntryAlreadyEnded,
|
|
Message: "A time entry that has already ended cannot be reopened into a running timer. Start a new timer instead.",
|
|
}
|
|
}
|
|
|
|
// ErrTimeEntryEndBeforeStart represents an error where a time entry's end time
|
|
// precedes its start time, which would persist a negative interval.
|
|
type ErrTimeEntryEndBeforeStart struct {
|
|
TimeEntryID int64
|
|
}
|
|
|
|
// IsErrTimeEntryEndBeforeStart checks if an error is ErrTimeEntryEndBeforeStart.
|
|
func IsErrTimeEntryEndBeforeStart(err error) bool {
|
|
_, ok := err.(ErrTimeEntryEndBeforeStart)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrTimeEntryEndBeforeStart) Error() string {
|
|
return fmt.Sprintf("Time entry end time is before its start time [TimeEntryID: %v]", err.TimeEntryID)
|
|
}
|
|
|
|
// ErrCodeTimeEntryEndBeforeStart holds the unique world-error code of this error
|
|
const ErrCodeTimeEntryEndBeforeStart = 18007
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrTimeEntryEndBeforeStart) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusBadRequest,
|
|
Code: ErrCodeTimeEntryEndBeforeStart,
|
|
Message: "A time entry's end time cannot be before its start time.",
|
|
}
|
|
}
|
|
|
|
// =================
|
|
// User export errors
|
|
// =================
|
|
|
|
// ErrUserDataExportDoesNotExist represents an error where a user has no ready data export to download.
|
|
type ErrUserDataExportDoesNotExist struct{}
|
|
|
|
// IsErrUserDataExportDoesNotExist checks if an error is ErrUserDataExportDoesNotExist.
|
|
func IsErrUserDataExportDoesNotExist(err error) bool {
|
|
_, ok := err.(ErrUserDataExportDoesNotExist)
|
|
return ok
|
|
}
|
|
|
|
func (err ErrUserDataExportDoesNotExist) Error() string {
|
|
return "No user data export found"
|
|
}
|
|
|
|
// ErrCodeUserDataExportDoesNotExist holds the unique world-error code of this error
|
|
const ErrCodeUserDataExportDoesNotExist = 19001
|
|
|
|
// HTTPError holds the http error description
|
|
func (err ErrUserDataExportDoesNotExist) HTTPError() web.HTTPError {
|
|
return web.HTTPError{
|
|
HTTPCode: http.StatusNotFound,
|
|
Code: ErrCodeUserDataExportDoesNotExist,
|
|
Message: "No user data export found.",
|
|
}
|
|
}
|