Fix unclear error messages in the API

Some API calls may have returned useless error messages such as

{"faultcode": "Client", "faultstring": " is not a valid option for ",
 "debuginfo": null}

when a DB constraint failed.

This commit improves the error message by reading the name of the
foreign key that failed from the exception.

The value of the parameters should have already been validated by WSME,
this exception is only thrown when there is an issue with the database
(corrupted DB, empty table or missing fields in a table).

Story 2009957
Task 44919

Change-Id: Idd6480bc0a7de7c42b34601172c2dae50077aa48
This commit is contained in:
Gregory Thiemonge 2022-04-04 11:20:20 +02:00
parent f64f2cdc6e
commit 57e006eac3
6 changed files with 26 additions and 20 deletions

View File

@ -159,11 +159,11 @@ class HealthMonitorController(base.BaseController):
lock_session, **hm_dict)
except odb_exceptions.DBDuplicateEntry as e:
raise exceptions.DuplicateHealthMonitor() from e
except odb_exceptions.DBReferenceError as e:
raise exceptions.InvalidOption(value=hm_dict.get(e.key),
option=e.key) from e
except odb_exceptions.DBError as e:
# TODO(blogan): will have to do separate validation protocol
# before creation or update since the exception messages
# do not give any information as to what constraint failed
raise exceptions.InvalidOption(value='', option='') from e
raise exceptions.APIException() from e
def _validate_healthmonitor_request_for_udp_sctp(self, request,
pool_protocol):

View File

@ -106,11 +106,11 @@ class L7PolicyController(base.BaseController):
**l7policy_dict)
except odb_exceptions.DBDuplicateEntry as e:
raise exceptions.IDAlreadyExists() from e
except odb_exceptions.DBReferenceError as e:
raise exceptions.InvalidOption(value=l7policy_dict.get(e.key),
option=e.key) from e
except odb_exceptions.DBError as e:
# TODO(blogan): will have to do separate validation protocol
# before creation or update since the exception messages
# do not give any information as to what constraint failed
raise exceptions.InvalidOption(value='', option='') from e
raise exceptions.APIException() from e
@wsme_pecan.wsexpose(l7policy_types.L7PolicyRootResponse,
body=l7policy_types.L7PolicyRootPOST, status_code=201)

View File

@ -112,11 +112,11 @@ class L7RuleController(base.BaseController):
return self.repositories.l7rule.create(lock_session, **l7rule_dict)
except odb_exceptions.DBDuplicateEntry as e:
raise exceptions.IDAlreadyExists() from e
except odb_exceptions.DBReferenceError as e:
raise exceptions.InvalidOption(value=l7rule_dict.get(e.key),
option=e.key) from e
except odb_exceptions.DBError as e:
# TODO(blogan): will have to do separate validation protocol
# before creation or update since the exception messages
# do not give any information as to what constraint failed
raise exceptions.InvalidOption(value='', option='') from e
raise exceptions.APIException() from e
@wsme_pecan.wsexpose(l7rule_types.L7RuleRootResponse,
body=l7rule_types.L7RuleRootPOST, status_code=201)

View File

@ -123,11 +123,11 @@ class MemberController(base.BaseController):
raise exceptions.DuplicateMemberEntry(
ip_address=member_dict.get('ip_address'),
port=member_dict.get('protocol_port')) from e
except odb_exceptions.DBReferenceError as e:
raise exceptions.InvalidOption(value=member_dict.get(e.key),
option=e.key) from e
except odb_exceptions.DBError as e:
# TODO(blogan): will have to do separate validation protocol
# before creation or update since the exception messages
# do not give any information as to what constraint failed
raise exceptions.InvalidOption(value='', option='') from e
raise exceptions.APIException() from e
return None
def _validate_pool_id(self, member_id, db_member_pool_id):

View File

@ -146,11 +146,11 @@ class PoolsController(base.BaseController):
listener_id=listener_id)
except odb_exceptions.DBDuplicateEntry as e:
raise exceptions.IDAlreadyExists() from e
except odb_exceptions.DBReferenceError as e:
raise exceptions.InvalidOption(value=pool_dict.get(e.key),
option=e.key) from e
except odb_exceptions.DBError as e:
# TODO(blogan): will have to do separate validation protocol
# before creation or update since the exception messages
# do not give any information as to what constraint failed
raise exceptions.InvalidOption(value='', option='') from e
raise exceptions.APIException() from e
def _is_only_specified_in_request(self, request, **kwargs):
request_attrs = []

View File

@ -0,0 +1,6 @@
---
fixes:
- |
The Octavia API returned an unhelpful message when a constraint failed
while creating an object in the DB. The error now contains the name and the
value of the parameter that breaks the constraints.