diff --git a/data/helpers.d/config b/data/helpers.d/config index 5970351f7..71d41fbe9 100644 --- a/data/helpers.d/config +++ b/data/helpers.d/config @@ -242,8 +242,20 @@ _ynh_app_config_validate() { fi if [ -n "$result" ] then - local key="YNH_ERROR_${short_setting}" - ynh_return "$key: \"$result\"" + # + # Return a yaml such as: + # + # validation_errors: + # some_key: "An error message" + # some_other_key: "Another error message" + # + # We use changes_validated to know if this is + # the first validation error + if [[ "$changes_validated" == true ]] + then + ynh_return "validation_errors:" + fi + ynh_return " ${short_setting}: \"$result\"" changes_validated=false fi done diff --git a/src/yunohost/app.py b/src/yunohost/app.py index e9712edb4..4047369e0 100644 --- a/src/yunohost/app.py +++ b/src/yunohost/app.py @@ -1695,9 +1695,7 @@ def app_config_set( Question.operation_logger = operation_logger - result = config_.set(key, value, args, args_file, operation_logger=operation_logger) - - return result + return config_.set(key, value, args, args_file, operation_logger=operation_logger) class AppConfigPanel(ConfigPanel): @@ -1715,7 +1713,18 @@ class AppConfigPanel(ConfigPanel): def _apply(self): env = {key: str(value) for key, value in self.new_values.items()} - self.errors = self._call_config_script("apply", env=env) + return_content = self._call_config_script("apply", env=env) + + # If the script returned validation error + # raise a ValidationError exception using + # the first key + if return_content: + for key, message in return_content.get("validation_errors").items(): + raise YunohostValidationError( + "app_argument_invalid", + name=key, + error=message, + ) def _call_config_script(self, action, env={}): from yunohost.hook import hook_exec diff --git a/src/yunohost/utils/config.py b/src/yunohost/utils/config.py index 744849199..6b491386f 100644 --- a/src/yunohost/utils/config.py +++ b/src/yunohost/utils/config.py @@ -135,6 +135,8 @@ class ConfigPanel: try: self._apply() + except YunohostError: + raise # Script got manually interrupted ... # N.B. : KeyboardInterrupt does not inherit from Exception except (KeyboardInterrupt, EOFError): @@ -152,16 +154,10 @@ class ConfigPanel: # Delete files uploaded from API FileQuestion.clean_upload_dirs() - if self.errors: - return { - "errors": self.errors, - } - self._reload_services() logger.success("Config updated as expected") operation_logger.success() - return {} def _get_toml(self): return read_toml(self.config_path)