From 2c1f6ecd92a5147158af712a5006d3e940fc3ef3 Mon Sep 17 00:00:00 2001 From: Christian Wolf Date: Wed, 28 Apr 2021 17:34:48 +0200 Subject: [PATCH 1/8] Clean up storage of updated/new recipes to avoid code duplication Signed-off-by: Christian Wolf --- src/components/RecipeEdit.vue | 67 +++++++++++++++++------------------ 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/src/components/RecipeEdit.vue b/src/components/RecipeEdit.vue index 597d28f64..6b964c6ad 100644 --- a/src/components/RecipeEdit.vue +++ b/src/components/RecipeEdit.vue @@ -564,47 +564,46 @@ 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}`) - }) - .catch((e) => { - // error + const request = (() => { + if(this.recipe_id) { + return this.$store.dispatch("updateRecipe", { recipe: this.recipe }) + } 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 + console.log("error on the server.") // TODO This must be implemented correctly + } 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(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 + }) + .catch((e) => { + console.log('terminal catch') + console.log(e) + }) }, setup() { this.fetchCategories() From 762c13acb44bb826edffce01e2140ac62804e177 Mon Sep 17 00:00:00 2001 From: Christian Wolf Date: Wed, 28 Apr 2021 17:57:31 +0200 Subject: [PATCH 2/8] Implement in the backend the check for existing recipes Signed-off-by: Christian Wolf --- lib/Controller/MainController.php | 9 +++++++++ lib/Controller/RecipeController.php | 19 +++++++++++++++---- lib/Exception/RecipeExistsException.php | 9 +++++++++ lib/Service/RecipeService.php | 5 +++-- src/components/RecipeEdit.vue | 13 ++++++++++++- 5 files changed, 48 insertions(+), 7 deletions(-) create mode 100644 lib/Exception/RecipeExistsException.php diff --git a/lib/Controller/MainController.php b/lib/Controller/MainController.php index d1db17817..08b546cc0 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..537a50487 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/RecipeEdit.vue b/src/components/RecipeEdit.vue index 6b964c6ad..7b3b3d38d 100644 --- a/src/components/RecipeEdit.vue +++ b/src/components/RecipeEdit.vue @@ -580,7 +580,18 @@ export default { if(e.response){ // Non 2xx state returned - console.log("error on the server.") // TODO This must be implemented correctly + + switch(e.response.status){ + case 409: + alert(e.response.data.msg) + break + + default: + // eslint-disable-next-line no-alert + alert(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", "No answer for request was received.")) From 22b0de818c400772abd9599d6dbacc8b263a2ee8 Mon Sep 17 00:00:00 2001 From: Christian Wolf Date: Wed, 28 Apr 2021 17:58:12 +0200 Subject: [PATCH 3/8] Cover return values of exceptions for downloads as well Signed-off-by: Christian Wolf --- src/components/AppNavi.vue | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/components/AppNavi.vue b/src/components/AppNavi.vue index 1e6329496..76b1c55b5 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( From 1a7abccfd3f012b4da877e76620336bad551f122 Mon Sep 17 00:00:00 2001 From: Christian Wolf Date: Wed, 28 Apr 2021 18:01:05 +0200 Subject: [PATCH 4/8] Update changelog Signed-off-by: Christian Wolf --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) 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 From da580b117c3d65247fd44639bd8bac92e307f25b Mon Sep 17 00:00:00 2001 From: Christian Wolf Date: Wed, 28 Apr 2021 18:07:12 +0200 Subject: [PATCH 5/8] Corrected PHP styles Signed-off-by: Christian Wolf --- lib/Controller/MainController.php | 12 ++++++------ lib/Controller/RecipeController.php | 20 ++++++++++---------- lib/Service/RecipeService.php | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/Controller/MainController.php b/lib/Controller/MainController.php index 08b546cc0..07b19322d 100755 --- a/lib/Controller/MainController.php +++ b/lib/Controller/MainController.php @@ -356,12 +356,12 @@ public function import() { 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); + $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 537a50487..d16cc2239 100755 --- a/lib/Controller/RecipeController.php +++ b/lib/Controller/RecipeController.php @@ -120,17 +120,17 @@ public function create() { $recipeData = $this->restParser->getParameters(); try { - $file = $this->service->addRecipe($recipeData); - $this->dbCacheService->addRecipe($file); - - return new DataResponse($file->getParent()->getId(), Http::STATUS_OK, ['Content-Type' => 'application/json']); + $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); + $json = [ + 'msg' => $ex->getMessage(), + 'file' => $ex->getFile(), + 'line' => $ex->getLine(), + ]; + return new JSONResponse($json, Http::STATUS_CONFLICT); } } diff --git a/lib/Service/RecipeService.php b/lib/Service/RecipeService.php index 6a5e06a28..2c7226d97 100755 --- a/lib/Service/RecipeService.php +++ b/lib/Service/RecipeService.php @@ -699,7 +699,7 @@ public function addRecipe($json) { $json['dateCreated'] = $now; if ($user_folder->nodeExists($json['name'])) { - throw new RecipeExistsException($this->il10n->t('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']); From e60dc724d1393bff90da9959d1abaf479a792b2b Mon Sep 17 00:00:00 2001 From: Christian Wolf Date: Wed, 28 Apr 2021 18:07:12 +0200 Subject: [PATCH 6/8] Corrected Vue styles Signed-off-by: Christian Wolf --- src/components/AppNavi.vue | 2 +- src/components/RecipeEdit.vue | 35 ++++++++++++++++++++++++----------- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/components/AppNavi.vue b/src/components/AppNavi.vue index 76b1c55b5..848ba13a3 100644 --- a/src/components/AppNavi.vue +++ b/src/components/AppNavi.vue @@ -287,7 +287,7 @@ export default { ) { 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 { diff --git a/src/components/RecipeEdit.vue b/src/components/RecipeEdit.vue index 7b3b3d38d..edffe5613 100644 --- a/src/components/RecipeEdit.vue +++ b/src/components/RecipeEdit.vue @@ -565,41 +565,54 @@ export default { const $this = this const request = (() => { - if(this.recipe_id) { - return this.$store.dispatch("updateRecipe", { recipe: this.recipe }) + if (this.recipe_id) { + return this.$store.dispatch("updateRecipe", { + recipe: this.recipe, + }) } else { - return this.$store.dispatch("createRecipe", { recipe: this.recipe }) + return this.$store.dispatch("createRecipe", { + recipe: this.recipe, + }) } })() - request.then((response) => { + request + .then((response) => { $this.$window.goTo(`/recipe/${response.data}`) }) .catch((e) => { // error - if(e.response){ + if (e.response) { // Non 2xx state returned - switch(e.response.status){ + switch (e.response.status) { case 409: alert(e.response.data.msg) break default: // eslint-disable-next-line no-alert - alert(t('cookbook', 'Unknown answer returned from server. See logs.')) + 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) { + } else if (e.request) { // eslint-disable-next-line no-alert - alert(t("cookbook", "No answer for request was received.")) + alert( + t("cookbook", "No answer for request was received.") + ) // eslint-disable-next-line no-console console.log(e) } else { // eslint-disable-next-line no-alert - alert(t("cookbook", "Could not start request to save recipe.")) + alert( + // prettier-ignore + t("cookbook","Could not start request to save recipe.") + ) // eslint-disable-next-line no-console console.log(e) } @@ -612,7 +625,7 @@ export default { $this.savingRecipe = false }) .catch((e) => { - console.log('terminal catch') + console.log("terminal catch") console.log(e) }) }, From bc990e975242b3d960038ffd2c42ca1de06611e4 Mon Sep 17 00:00:00 2001 From: Christian Wolf Date: Wed, 12 May 2021 15:06:26 +0200 Subject: [PATCH 7/8] Fixed promise issue Signed-off-by: Christian Wolf --- src/components/RecipeEdit.vue | 4 ---- src/store/index.js | 5 +++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/components/RecipeEdit.vue b/src/components/RecipeEdit.vue index edffe5613..c63ba6250 100644 --- a/src/components/RecipeEdit.vue +++ b/src/components/RecipeEdit.vue @@ -624,10 +624,6 @@ export default { }) $this.savingRecipe = false }) - .catch((e) => { - console.log("terminal catch") - console.log(e) - }) }, setup() { this.fetchCategories() 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 From 6da7ae8cc49f71e51796e7c7cc4d68e9b70073d7 Mon Sep 17 00:00:00 2001 From: Christian Wolf Date: Wed, 12 May 2021 15:15:06 +0200 Subject: [PATCH 8/8] Update vue files with current style Signed-off-by: Christian Wolf --- src/components/AppSettings.vue | 3 ++- src/components/RecipeView.vue | 15 ++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) 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/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) {