Error system and error handling of AssignmentService#7
Conversation
aac9690 to
50f3f7a
Compare
This system allows developers to wrap code in a function which takes an error scope. This scope can contain one or more application errors, each of which represent a step that can go wrong when the code is executed. When one of the errors expected in the scope is raised, it is resolved to a customized error message, which contains: - a HTTP response code - a title - a description - a link to documentation explaining the error This error is then raised and bubbled up to the controller, where it is returned to the user. Should an error be raised that is not expected in the scope, an UnexpectedError exception will be raised, which tells the developer that a known error was raised in a scope it was not expected to occur in. Should a non-ApplicationError exception be raised, an UnknownError will be raised, telling the user that an actual bug is present.
- finder:
- (ADR-003-005-004-001) invalid target type
Raised when the user supplied an unsupported target type
- find_target:
- (ADR-003-005-005-001) target not found
Raised when the user supplied a target id which does not exist
Introduces error codes:
- ADR-003-005-004-001
- ADR-003-005-005-001
…vice This new base-class allows definition of service-global methods and imports. Includes Ansible director error helpers.
Usage of find_target enables error-handling and deduplicates code.
50f3f7a to
6dfa054
Compare
| @@ -0,0 +1,65 @@ | |||
| # frozen_string_literal: true | |||
There was a problem hiding this comment.
I don't think we should have "our own" erorr code system.
Please have a look at: https://github.com/theforeman/foreman/blob/develop/lib/foreman/exception.rb#L8
if we want to have something better than this, we should take the time to get this into foreman core so that other plugins (and core) can re-use this.
There was a problem hiding this comment.
I disagree for multiple reasons:
- The error code calulated by the function in core serves, at best, as a lookup for the controller. And even for that, a lookup table is required.
- Said table can only be generated for core, which is why Foreman::Exception is not used in plugins.
- Any upstream work is not really in the scope of this PR. Using our system in an existing plugin would require extensive work.
- Lastly, this is pretty much just an abstraction over the common begin-rescue strategy used in plugins.
There was a problem hiding this comment.
Why not just throw an exception without these error codes?
There was a problem hiding this comment.
General benefits of error codes aside, raising an exception in the business logic would require bloating of the BL with a message, a response code and a title.
This already fixes that.
| end | ||
| # rubocop:enable Style/GuardClause | ||
| rescue StandardError | ||
| raise ::ForemanAnsibleDirector::Errors::UnknownError |
There was a problem hiding this comment.
instead of hiding the real issue, what about just let it unhandled and pass it through?
| end | ||
| end | ||
|
|
||
| class ErrorScopeRescue |
There was a problem hiding this comment.
this is currently not used. what is the purpose of this and how should it work? I think it would be better to handle the exception at the code section where they really happen
| @@ -0,0 +1,18 @@ | |||
| 003: | |||
There was a problem hiding this comment.
this file needs to be auto-generated from the error objects
| # TODO: Null check target | ||
| finder = finder(type: target_type) | ||
| finder.find_by(id: target_id) | ||
| error_scope(['ADR-003-005-005-001']).try do |
There was a problem hiding this comment.
this duplicates the error codes like this https://github.com/ATIX-AG/foreman_ansible_director/pull/7/changes#diff-3fd51f00ed42919881336d2ff09ded12a6ced416213ec0dcb811917d5bfb7c44R61
I know, its about tell error_scope which error may occur. unknown error should "flow through"
| end | ||
|
|
||
| ERROR_OBJECTS = HashWithIndifferentAccess.new({ | ||
| "ADR-003-005-004-001": { |
There was a problem hiding this comment.
please use a easier error code scheme like "ADR-001-001" instead of 4 columns
|
As a user, I would appreciate a good error message. Example: If I create an Ansible Execution Environment via WebUI & do not provide a string in "Base image URL", the UI shows Instead, it would be great to read "Error: Base image URL cannot be empty: Please provide a base-image URL." |
|
@sbernhard & @Thorben-D Another example:
|
This error happened when I tried to query the API but mistakenly took the lifecycle environment path ID instead of the lifecycle environment ID. As a user, I though that my Foreman+Katello instance ran into an error aka. there is an issue in the code. It would be so more nicer if the JSON returned the same status but a useful error message, for example, "Lifecycle environment ID not found.". cc @sbernhard & @Thorben-D |
|
I found a great error message example in Ansible Director: Possible minor improvement: Add the name of the key "base_image_url" to the error message. But it's already extremely helpful when debugging issue to understand what failed, why, and how to fix it. |
|
Please prioritze having error messages in Ansible Director. {
"error": {
"message": "Task bc31a2ec-e778-4ec6-95d7-a2bb56d546bd: NoMethodError: undefined method `each' for nil:NilClass"
}
}Is the return value of the API on nightly if you try to import an Ansible collection from Galaxy that is already present. As a user, this is less than ideal. |
|
Instead of implementing our own error code system, please use named exceptions as this is used in foreman, katello and other plugins. Like: https://github.com/Katello/katello/blob/master/app/lib/katello/errors.rb |
Copied from "feat(errors): add custom error system":
This system allows developers to wrap code in a function which
takes an error scope.
This scope can contain one or more application errors, each of which
represent a step that can go wrong when the code is executed.
When one of the errors expected in the scope is raised, it is resolved
to a customized error message, which contains:
This error is then raised and bubbled up to the controller, where it is
returned to the user.
Should an error be raised that is not expected in the scope, an UnexpectedError
exception will be raised, which tells the developer that a known error was
raised in a scope it was not expected to occur in.
Should a non-ApplicationError exception be raised, an UnknownError will be
raised, telling the user that an actual bug is present.
Furthermore, this PR makes use of that system for the AssignmentService.
Requires: #6
Requires: #1