diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bc2b3bd7..c9770da18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,8 @@ [#699](https://github.com/nextcloud/cookbook/pull/699) @christianlupus - Enable stalebot [#700](https://github.com/nextcloud/cookbook/pull/700) @christianlupus +- Correct error messages when recipe already exists + [#702](https://github.com/nextcloud/cookbook/pull/702) @christianlupus ## 0.8.4 - 2021-03-08 diff --git a/lib/Controller/MainController.php b/lib/Controller/MainController.php index d1db17817..07b19322d 100755 --- a/lib/Controller/MainController.php +++ b/lib/Controller/MainController.php @@ -12,6 +12,8 @@ use OCA\Cookbook\Service\DbCacheService; use OCA\Cookbook\Helper\RestParameterParser; use OCA\Cookbook\Exception\UserFolderNotWritableException; +use OCA\Cookbook\Exception\RecipeExistsException; +use OCP\AppFramework\Http\JSONResponse; class MainController extends Controller { protected $appName; @@ -353,6 +355,13 @@ public function import() { $this->dbCacheService->addRecipe($recipe_file); return new DataResponse($recipe_json, Http::STATUS_OK, ['Content-Type' => 'application/json']); + } catch (RecipeExistsException $ex) { + $json = [ + 'msg' => $ex->getMessage(), + 'line' => $ex->getLine(), + 'file' => $ex->getFile(), + ]; + return new JSONResponse($json, Http::STATUS_CONFLICT); } catch (\Exception $e) { return new DataResponse($e->getMessage(), 400); } diff --git a/lib/Controller/RecipeController.php b/lib/Controller/RecipeController.php index a6ea7aa8e..d16cc2239 100755 --- a/lib/Controller/RecipeController.php +++ b/lib/Controller/RecipeController.php @@ -12,7 +12,9 @@ use OCA\Cookbook\Service\RecipeService; use OCP\IURLGenerator; use OCA\Cookbook\Service\DbCacheService; +use OCA\Cookbook\Exception\RecipeExistsException; use OCA\Cookbook\Helper\RestParameterParser; +use OCP\AppFramework\Http\JSONResponse; class RecipeController extends Controller { /** @@ -117,10 +119,19 @@ public function create() { $this->dbCacheService->triggerCheck(); $recipeData = $this->restParser->getParameters(); - $file = $this->service->addRecipe($recipeData); - $this->dbCacheService->addRecipe($file); - - return new DataResponse($file->getParent()->getId(), Http::STATUS_OK, ['Content-Type' => 'application/json']); + try { + $file = $this->service->addRecipe($recipeData); + $this->dbCacheService->addRecipe($file); + + return new DataResponse($file->getParent()->getId(), Http::STATUS_OK, ['Content-Type' => 'application/json']); + } catch (RecipeExistsException $ex) { + $json = [ + 'msg' => $ex->getMessage(), + 'file' => $ex->getFile(), + 'line' => $ex->getLine(), + ]; + return new JSONResponse($json, Http::STATUS_CONFLICT); + } } /** diff --git a/lib/Exception/RecipeExistsException.php b/lib/Exception/RecipeExistsException.php new file mode 100644 index 000000000..672ce3618 --- /dev/null +++ b/lib/Exception/RecipeExistsException.php @@ -0,0 +1,9 @@ +nodeExists($json['name'])) { - throw new Exception('Another recipe with that name already exists'); + throw new RecipeExistsException($this->il10n->t('Another recipe with that name already exists')); } $recipe_folder->move($new_path); @@ -698,7 +699,7 @@ public function addRecipe($json) { $json['dateCreated'] = $now; if ($user_folder->nodeExists($json['name'])) { - throw new Exception('Another recipe with that name already exists'); + throw new RecipeExistsException($this->il10n->t('Another recipe with that name already exists')); } $recipe_folder = $user_folder->newFolder($json['name']); diff --git a/src/components/AppNavi.vue b/src/components/AppNavi.vue index 1e6329496..848ba13a3 100644 --- a/src/components/AppNavi.vue +++ b/src/components/AppNavi.vue @@ -285,8 +285,15 @@ export default { e2.response.status >= 400 && e2.response.status < 500 ) { - // eslint-disable-next-line no-alert - alert(e2.response.data) + if (e2.response.status == 409) { + // There was a recipe found with the same name + + // eslint-disable-next-line no-alert + alert(e2.response.data.msg) + } else { + // eslint-disable-next-line no-alert + alert(e2.response.data) + } } else { console.error(e2) alert( diff --git a/src/components/AppSettings.vue b/src/components/AppSettings.vue index 49fd1c758..130a55838 100644 --- a/src/components/AppSettings.vue +++ b/src/components/AppSettings.vue @@ -212,7 +212,8 @@ export default { this.resetPrintImage = false if (config) { this.printImage = config.print_image - this.showTagCloudInRecipeList = this.$store.state.localSettings.showTagCloudInRecipeList + this.showTagCloudInRecipeList = + this.$store.state.localSettings.showTagCloudInRecipeList this.updateInterval = config.update_interval this.recipeFolder = config.folder } else { diff --git a/src/components/RecipeEdit.vue b/src/components/RecipeEdit.vue index 597d28f64..c63ba6250 100644 --- a/src/components/RecipeEdit.vue +++ b/src/components/RecipeEdit.vue @@ -564,47 +564,66 @@ export default { this.$store.dispatch("setSavingRecipe", { saving: true }) const $this = this - if (this.recipe.id) { - this.$store - .dispatch("updateRecipe", { recipe: this.recipe }) - .then((response) => { - $this.$window.goTo(`/recipe/${response.data}`) + const request = (() => { + if (this.recipe_id) { + return this.$store.dispatch("updateRecipe", { + recipe: this.recipe, }) - .catch((e) => { - // error + } else { + return this.$store.dispatch("createRecipe", { + recipe: this.recipe, + }) + } + })() + + request + .then((response) => { + $this.$window.goTo(`/recipe/${response.data}`) + }) + .catch((e) => { + // error + + if (e.response) { + // Non 2xx state returned + + switch (e.response.status) { + case 409: + alert(e.response.data.msg) + break + + default: + // eslint-disable-next-line no-alert + alert( + // prettier-ignore + t("cookbook","Unknown answer returned from server. See logs.") + ) + // eslint-disable-next-line no-console + console.log(e.response) + } + } else if (e.request) { // eslint-disable-next-line no-alert - alert(t("cookbook", "Recipe could not be saved")) + alert( + t("cookbook", "No answer for request was received.") + ) // eslint-disable-next-line no-console console.log(e) - }) - .then(() => { - // finally - $this.$store.dispatch("setSavingRecipe", { - saving: false, - }) - $this.savingRecipe = false - }) - } else { - this.$store - .dispatch("createRecipe", { recipe: this.recipe }) - .then((response) => { - $this.$window.goTo(`/recipe/${response.data}`) - }) - .catch((e) => { - // error + } else { // eslint-disable-next-line no-alert - alert(t("cookbook", "Recipe could not be saved")) + alert( + // prettier-ignore + t("cookbook","Could not start request to save recipe.") + ) // eslint-disable-next-line no-console console.log(e) + } + }) + .then(() => { + // finally + $this.$store.dispatch("setSavingRecipe", { + saving: false, }) - .then(() => { - // finally - $this.$store.dispatch("setSavingRecipe", { - saving: false, - }) - $this.savingRecipe = false - }) - } + $this.savingRecipe = false + }) }, setup() { this.fetchCategories() diff --git a/src/components/RecipeView.vue b/src/components/RecipeView.vue index 6602132c4..3bf202417 100644 --- a/src/components/RecipeView.vue +++ b/src/components/RecipeView.vue @@ -355,9 +355,8 @@ export default { } if (this.$store.state.recipe.cookTime) { - const cookT = this.$store.state.recipe.cookTime.match( - /PT(\d+?)H(\d+?)M/ - ) + const cookT = + this.$store.state.recipe.cookTime.match(/PT(\d+?)H(\d+?)M/) const hh = parseInt(cookT[1], 10) const mm = parseInt(cookT[2], 10) if (hh > 0 || mm > 0) { @@ -366,9 +365,8 @@ export default { } if (this.$store.state.recipe.prepTime) { - const prepT = this.$store.state.recipe.prepTime.match( - /PT(\d+?)H(\d+?)M/ - ) + const prepT = + this.$store.state.recipe.prepTime.match(/PT(\d+?)H(\d+?)M/) const hh = parseInt(prepT[1], 10) const mm = parseInt(prepT[2], 10) if (hh > 0 || mm > 0) { @@ -377,9 +375,8 @@ export default { } if (this.$store.state.recipe.totalTime) { - const totalT = this.$store.state.recipe.totalTime.match( - /PT(\d+?)H(\d+?)M/ - ) + const totalT = + this.$store.state.recipe.totalTime.match(/PT(\d+?)H(\d+?)M/) const hh = parseInt(totalT[1], 10) const mm = parseInt(totalT[2], 10) if (hh > 0 || mm > 0) { diff --git a/src/store/index.js b/src/store/index.js index cefa2b3c2..97f979202 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -119,13 +119,14 @@ export default new Vuex.Store({ url: `${window.baseUrl}/api/recipes`, data: recipe, }) - request.then(() => { + return request.then((v) => { // Refresh navigation to display changes c.dispatch("setAppNavigationRefreshRequired", { isRequired: true, }) + + return v }) - return request }, /** * Delete recipe on the server