Page MenuHomePhabricator

dbctl instance edit crashes with "exceptions must derive from BaseException" instead of showing real validation errors
Open, Needs TriagePublic

Description

When editing a dbconfig-instance object via dbctl instance <host> edit and the edit fails semantic validation (i.e. passes JSON schema but fails DbConfig.check_instance/check_config), the CLI can crash with the unhelpful error:

Execution FAILED
Reported errors:
exceptions must derive from BaseException

instead of surfacing the actual reason the edit is invalid.

The problem seems to be: conftool/extensions/dbconfig/entities.py, DbEditAction._validate_edit():

def _validate_edit(self) -> Tuple[bool, Any]:
    try:
        self.entity.validate(self.edited)
        to_check = copy.deepcopy(self.entity)
        to_check.from_net(self.edited)
        errors = self.checker(to_check)          # a list[str], not an exception
        return (len(errors) == 0, errors)
    except Exception as e:
        ...
        return (False, e)

When the semantic checker (e.g. check_instance) returns a non-empty list[str] (not an exception), that list is passed as err into the base class EditAction.run() (conftool/action.py):

valid, err = self._validate_edit()
if valid:
    break
else:
    self._check_amend(err)

and then into _check_amend:

elif lc_answer == "n":
    raise exception   # `exception` is the list[str] here

raise <list> produces Python's generic TypeError: exceptions must derive from BaseException, discarding thally, the error list is never printed to the user before the "Continue editing? [y/n]" prompt in this codepath — only the except Exception branch prints diagnostic info — so even without hitting "n", the user has no visibility into why the edit was rejected.

I am going to edit https://wikitech.wikimedia.org/wiki/Dbctl to make sure we set min_replicas to 0 when starting a new section and will reference this ticket.