diff --git a/errors/errors.go b/errors/errors.go index 5ec364c0..5848ee71 100644 --- a/errors/errors.go +++ b/errors/errors.go @@ -19,3 +19,26 @@ var ( ErrSourceIsParent = errors.New("source is parent") ErrRootUserDeletion = errors.New("user with id 1 can't be deleted") ) + +type HTTPError struct { + Err error + Type string +} + +func (e *HTTPError) Error() string { + if e.Err == nil { + return e.Type + } + return e.Err.Error() +} + +func (e *HTTPError) Unwrap() error { + return e.Err +} + +func NewHTTPError(err error, errType string) error { + return &HTTPError{ + Err: err, + Type: errType, + } +} diff --git a/frontend/src/components/prompts/Archive.vue b/frontend/src/components/prompts/Archive.vue index 6bf531cc..69a800a8 100644 --- a/frontend/src/components/prompts/Archive.vue +++ b/frontend/src/components/prompts/Archive.vue @@ -76,15 +76,15 @@ export default { try { buttons.loading("archive"); - this.$store.commit("closeHovers"); await api.archive(uri, this.name, format, ...items); + this.$store.commit("closeHovers"); this.$store.commit("setReload", true); + this.$store.dispatch("quota/fetch", 3000); } catch (e) { this.$showError(e); } finally { buttons.done("archive"); } - this.$store.dispatch("quota/fetch", 3000); }, }, }; diff --git a/frontend/src/i18n/ar_AR.json b/frontend/src/i18n/ar_AR.json index 6953a469..31a2947e 100644 --- a/frontend/src/i18n/ar_AR.json +++ b/frontend/src/i18n/ar_AR.json @@ -48,7 +48,13 @@ "connection": "The server can't be reached.", "forbidden": "You don't have permissions to access this.", "internal": "لقد حدث خطأ ما.", - "notFound": "لا يمكن الوصول لهذا المحتوى." + "notFound": "لا يمكن الوصول لهذا المحتوى.", + "resource": { + "alreadyExists": "Resource with such name already exists" + }, + "validation": { + "emptyName": "Resource name can't be empty" + } }, "files": { "body": "الصفحة", diff --git a/frontend/src/i18n/en_GB.json b/frontend/src/i18n/en_GB.json index 1f439086..6dd7a5ae 100644 --- a/frontend/src/i18n/en_GB.json +++ b/frontend/src/i18n/en_GB.json @@ -48,7 +48,13 @@ "connection": "The server can't be reached.", "forbidden": "You don't have permissions to access this.", "internal": "Something really went wrong.", - "notFound": "This location can't be reached." + "notFound": "This location can't be reached.", + "resource": { + "alreadyExists": "Resource with such name already exists" + }, + "validation": { + "emptyName": "Resource name can't be empty" + } }, "files": { "body": "Body", diff --git a/frontend/src/i18n/es_AR.json b/frontend/src/i18n/es_AR.json index d689a5e4..7e771d1e 100644 --- a/frontend/src/i18n/es_AR.json +++ b/frontend/src/i18n/es_AR.json @@ -48,7 +48,13 @@ "connection": "The server can't be reached.", "forbidden": "No tienes los permisos necesarios para acceder.", "internal": "La verdad es que algo ha ido mal.", - "notFound": "No se puede acceder a este lugar." + "notFound": "No se puede acceder a este lugar.", + "resource": { + "alreadyExists": "Resource with such name already exists" + }, + "validation": { + "emptyName": "Resource name can't be empty" + } }, "files": { "body": "Cuerpo", diff --git a/frontend/src/i18n/es_CO.json b/frontend/src/i18n/es_CO.json index d689a5e4..7e771d1e 100644 --- a/frontend/src/i18n/es_CO.json +++ b/frontend/src/i18n/es_CO.json @@ -48,7 +48,13 @@ "connection": "The server can't be reached.", "forbidden": "No tienes los permisos necesarios para acceder.", "internal": "La verdad es que algo ha ido mal.", - "notFound": "No se puede acceder a este lugar." + "notFound": "No se puede acceder a este lugar.", + "resource": { + "alreadyExists": "Resource with such name already exists" + }, + "validation": { + "emptyName": "Resource name can't be empty" + } }, "files": { "body": "Cuerpo", diff --git a/frontend/src/i18n/es_ES.json b/frontend/src/i18n/es_ES.json index d689a5e4..7e771d1e 100644 --- a/frontend/src/i18n/es_ES.json +++ b/frontend/src/i18n/es_ES.json @@ -48,7 +48,13 @@ "connection": "The server can't be reached.", "forbidden": "No tienes los permisos necesarios para acceder.", "internal": "La verdad es que algo ha ido mal.", - "notFound": "No se puede acceder a este lugar." + "notFound": "No se puede acceder a este lugar.", + "resource": { + "alreadyExists": "Resource with such name already exists" + }, + "validation": { + "emptyName": "Resource name can't be empty" + } }, "files": { "body": "Cuerpo", diff --git a/frontend/src/i18n/es_MX.json b/frontend/src/i18n/es_MX.json index d689a5e4..7e771d1e 100644 --- a/frontend/src/i18n/es_MX.json +++ b/frontend/src/i18n/es_MX.json @@ -48,7 +48,13 @@ "connection": "The server can't be reached.", "forbidden": "No tienes los permisos necesarios para acceder.", "internal": "La verdad es que algo ha ido mal.", - "notFound": "No se puede acceder a este lugar." + "notFound": "No se puede acceder a este lugar.", + "resource": { + "alreadyExists": "Resource with such name already exists" + }, + "validation": { + "emptyName": "Resource name can't be empty" + } }, "files": { "body": "Cuerpo", diff --git a/frontend/src/i18n/fr_FR.json b/frontend/src/i18n/fr_FR.json index ff6fd271..bd6e0c92 100644 --- a/frontend/src/i18n/fr_FR.json +++ b/frontend/src/i18n/fr_FR.json @@ -48,7 +48,13 @@ "connection": "The server can't be reached.", "forbidden": "You don't have permissions to access this.", "internal": "Aïe ! Quelque chose s'est mal passé.", - "notFound": "Impossible d'accéder à cet emplacement." + "notFound": "Impossible d'accéder à cet emplacement.", + "resource": { + "alreadyExists": "Resource with such name already exists" + }, + "validation": { + "emptyName": "Resource name can't be empty" + } }, "files": { "body": "Corps", diff --git a/frontend/src/i18n/id_ID.json b/frontend/src/i18n/id_ID.json index 1f439086..6dd7a5ae 100644 --- a/frontend/src/i18n/id_ID.json +++ b/frontend/src/i18n/id_ID.json @@ -48,7 +48,13 @@ "connection": "The server can't be reached.", "forbidden": "You don't have permissions to access this.", "internal": "Something really went wrong.", - "notFound": "This location can't be reached." + "notFound": "This location can't be reached.", + "resource": { + "alreadyExists": "Resource with such name already exists" + }, + "validation": { + "emptyName": "Resource name can't be empty" + } }, "files": { "body": "Body", diff --git a/frontend/src/i18n/lt_LT.json b/frontend/src/i18n/lt_LT.json index 1f439086..6dd7a5ae 100644 --- a/frontend/src/i18n/lt_LT.json +++ b/frontend/src/i18n/lt_LT.json @@ -48,7 +48,13 @@ "connection": "The server can't be reached.", "forbidden": "You don't have permissions to access this.", "internal": "Something really went wrong.", - "notFound": "This location can't be reached." + "notFound": "This location can't be reached.", + "resource": { + "alreadyExists": "Resource with such name already exists" + }, + "validation": { + "emptyName": "Resource name can't be empty" + } }, "files": { "body": "Body", diff --git a/frontend/src/i18n/pt_BR.json b/frontend/src/i18n/pt_BR.json index 486bb302..5b4b484a 100644 --- a/frontend/src/i18n/pt_BR.json +++ b/frontend/src/i18n/pt_BR.json @@ -48,7 +48,13 @@ "connection": "The server can't be reached.", "forbidden": "You don't have permissions to access this.", "internal": "Ops! Algum erro ocorreu.", - "notFound": "Ops! Nada foi encontrado." + "notFound": "Ops! Nada foi encontrado.", + "resource": { + "alreadyExists": "Resource with such name already exists" + }, + "validation": { + "emptyName": "Resource name can't be empty" + } }, "files": { "body": "Corpo", diff --git a/frontend/src/i18n/pt_PT.json b/frontend/src/i18n/pt_PT.json index 91cde010..c4dbbee5 100644 --- a/frontend/src/i18n/pt_PT.json +++ b/frontend/src/i18n/pt_PT.json @@ -48,7 +48,13 @@ "connection": "The server can't be reached.", "forbidden": "Não tem permissões para aceder a isto", "internal": "Algo correu bastante mal.", - "notFound": "Esta localização não é alcançável." + "notFound": "Esta localização não é alcançável.", + "resource": { + "alreadyExists": "Resource with such name already exists" + }, + "validation": { + "emptyName": "Resource name can't be empty" + } }, "files": { "body": "Corpo", diff --git a/frontend/src/i18n/ru_RU.json b/frontend/src/i18n/ru_RU.json index 488dbc93..3b04bf87 100644 --- a/frontend/src/i18n/ru_RU.json +++ b/frontend/src/i18n/ru_RU.json @@ -48,7 +48,13 @@ "connection": "The server can't be reached.", "forbidden": "У вас нет прав доступа к этому.", "internal": "Что-то пошло не так.", - "notFound": "Неправильная ссылка." + "notFound": "Неправильная ссылка.", + "resource": { + "alreadyExists": "Resource with such name already exists" + }, + "validation": { + "emptyName": "Resource name can't be empty" + } }, "files": { "body": "Тело", diff --git a/frontend/src/i18n/tr_TR.json b/frontend/src/i18n/tr_TR.json index 1f439086..6dd7a5ae 100644 --- a/frontend/src/i18n/tr_TR.json +++ b/frontend/src/i18n/tr_TR.json @@ -48,7 +48,13 @@ "connection": "The server can't be reached.", "forbidden": "You don't have permissions to access this.", "internal": "Something really went wrong.", - "notFound": "This location can't be reached." + "notFound": "This location can't be reached.", + "resource": { + "alreadyExists": "Resource with such name already exists" + }, + "validation": { + "emptyName": "Resource name can't be empty" + } }, "files": { "body": "Body", diff --git a/frontend/src/i18n/uk_UA.json b/frontend/src/i18n/uk_UA.json index 1f439086..6dd7a5ae 100644 --- a/frontend/src/i18n/uk_UA.json +++ b/frontend/src/i18n/uk_UA.json @@ -48,7 +48,13 @@ "connection": "The server can't be reached.", "forbidden": "You don't have permissions to access this.", "internal": "Something really went wrong.", - "notFound": "This location can't be reached." + "notFound": "This location can't be reached.", + "resource": { + "alreadyExists": "Resource with such name already exists" + }, + "validation": { + "emptyName": "Resource name can't be empty" + } }, "files": { "body": "Body", diff --git a/frontend/src/i18n/zh_CN.json b/frontend/src/i18n/zh_CN.json index 4750ae3b..10c6e658 100644 --- a/frontend/src/i18n/zh_CN.json +++ b/frontend/src/i18n/zh_CN.json @@ -48,7 +48,13 @@ "connection": "The server can't be reached.", "forbidden": "你无权限访问", "internal": "服务器出了点问题。", - "notFound": "找不到文件。" + "notFound": "找不到文件。", + "resource": { + "alreadyExists": "Resource with such name already exists" + }, + "validation": { + "emptyName": "Resource name can't be empty" + } }, "files": { "body": "内容", diff --git a/frontend/src/utils/vue.js b/frontend/src/utils/vue.js index 74df7acc..3172a10d 100644 --- a/frontend/src/utils/vue.js +++ b/frontend/src/utils/vue.js @@ -45,9 +45,18 @@ Vue.prototype.$showError = (error, displayReport = true) => { ); } + let message = error.message || error; + let matches = /\[(.+)\]/.exec(message); + if (matches && matches.length > 1) { + let key = "errors." + matches[1]; + if (i18n.te(key)) { + message = i18n.t(key); + } + } + let n = new Noty( Object.assign({}, notyDefault, { - text: error.message || error, + text: message, type: "error", timeout: null, buttons: btns, diff --git a/http/data.go b/http/data.go index 84c2ef41..4259b246 100644 --- a/http/data.go +++ b/http/data.go @@ -7,6 +7,7 @@ import ( "github.com/tomasen/realip" + "github.com/filebrowser/filebrowser/v2/errors" "github.com/filebrowser/filebrowser/v2/rules" "github.com/filebrowser/filebrowser/v2/runner" "github.com/filebrowser/filebrowser/v2/settings" @@ -65,8 +66,11 @@ func handle(fn handleFunc, prefix string, store *storage.Storage, server *settin }) if status != 0 { - txt := http.StatusText(status) - http.Error(w, strconv.Itoa(status)+" "+txt, status) + txt := strconv.Itoa(status) + " " + http.StatusText(status) + if httpErr, ok := err.(*errors.HTTPError); ok { + txt += " [" + httpErr.Type + "]" + } + http.Error(w, txt, status) } if status >= 400 || err != nil { diff --git a/http/resource.go b/http/resource.go index f4adc8de..5813b665 100644 --- a/http/resource.go +++ b/http/resource.go @@ -489,7 +489,7 @@ func archiveHandler(r *http.Request, d *data) (int, error) { archFile, err := parseQueryFilename(r, destDir) if err != nil { - return http.StatusBadRequest, err + return http.StatusUnprocessableEntity, errors.NewHTTPError(err, "validation.emptyName") } extension, ar, err := parseArchiver(r.URL.Query().Get("algo")) @@ -501,7 +501,7 @@ func archiveHandler(r *http.Request, d *data) (int, error) { _, err = d.user.Fs.Stat(archFile) if err == nil { - return http.StatusConflict, nil + return http.StatusUnprocessableEntity, errors.NewHTTPError(err, "resource.alreadyExists") } dir, _ = path.Split(archFile)