Skip to content

Commit

Permalink
Update documentation and prepare release (#29)
Browse files Browse the repository at this point in the history
Fixes #16, #22 
---------
Co-authored-by: Christoph Pirkl <[email protected]>
  • Loading branch information
Nicoretti authored Sep 27, 2023
1 parent f10b253 commit 7934de8
Show file tree
Hide file tree
Showing 12 changed files with 110 additions and 164 deletions.
71 changes: 55 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,41 +1,74 @@
# Error Reporting Python
# Exasol Error Reporting

This project contains a python library for describing Exasol error messages.
This project contains a Python library for describing Exasol error messages.
This library lets you define errors with a uniform set of attributes.
Furthermore, the error message is implemented to be parseable,
so that you can extract an error catalog from the code.

## In a Nutshell

Create an error object:
### Install the library

```python
exa_error_obj = ExaError.message_builder('E-TEST-1')
.message("Not enough space on device {{device}}.")
.mitigation("Delete something from {{device}}.")
.mitigation("Create larger partition.")
.parameter("device", "/dev/sda1", "name of the device")
```shell
pip install exasol-error-reporting
```

Use it as string:
### Create a Simple Error

```python
from exasol import error

error1 = error.ExaError(
"E-TEST-1", "A trivial error", "No mitigation available", {}
)
```

### Specify Multiple Mitigations
```python
print(exa_error_obj)
from exasol import error

error2 = error.ExaError(
"E-TEST-2",
"Fire in the server room",
[
"Use the fire extinguisher",
"Flood the room with halon gas (Attention: be sure no humans in the room!)"
],
{}
)
```

Result:
### Error Parameter(s) without description

```python
from exasol import error

error3 = error.ExaError(
"E-TEST-2",
"Not enough space on device {{device}}.",
"Delete something from {{device}}.",
{"device": "/dev/sda1"},
)
```
E-TEST-1: Not enough space on device '/dev/sda1'. Known mitigations:
* Delete something from '/dev/sda1'.
* Create larger partition.
### Error with detailed Parameter(s)

```python
from exasol import error
from exasol.error import Parameter

error4 = error.ExaError(
"E-TEST-2",
"Not enough space on device {{device}}.",
"Delete something from {{device}}.",
{"device": Parameter("/dev/sda1", "name of the device")},
)
```

Check out the [user guide](doc/user_guide/user_guide.md) for more details.

## Tooling

The `error-reporting-python` library comes with a command line tool (`ec`) which also can be invoked
The `exasol-error-reporting` library comes with a command line tool (`ec`) which also can be invoked
by using its package/module entry point (`python -m exasol.error`).
For detailed information about the usage consider consulting the help `ec --help` or `python -m exasol.error --help`.

Expand All @@ -58,6 +91,12 @@ you can use the generate subcommand.
ec generate NAME VERSION PACKAGE_ROOT > error-codes.json
```

## Known Issues

* [Throws exception on invalid error code format](https://github.com/exasol/error-reporting-python/issues/27)
* [Single mitigations only can be passed within a list](https://github.com/exasol/error-reporting-python/issues/26)
* [Named parameters do not work for error construction](https://github.com/exasol/error-reporting-python/issues/25)

### Information for Users

* [User Guide](doc/user_guide/user_guide.md)
Expand Down
2 changes: 2 additions & 0 deletions doc/changes/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Changelog

* [unreleased](unreleased.md)
* [0.4.0](changes_0.4.0.md)
* [0.3.0](changes_0.3.0.md)
* [0.2.0](changes_0.2.0.md)
* [0.1.0](changes_0.1.0.md)
18 changes: 13 additions & 5 deletions doc/changes/changes_0.4.0.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
# error-reporting-python 0.4.0, released T.B.D
# exasol-error-reporting 0.4.0, released 2023-09-27

Code Name: T.B.D
Code Name: API Rework and package renaming

## Summary

T.B.D
Reworked the API to be more pythonic and easier to parse. Also the package has
been renamed in order to fit the pypi naming scheme.

## Feature
### Feature
- #4: Add error parser/crawler cli tool

### Refactoring

- Renamed python package from `exasol-error-reporting-python` to `exasol-error-reporting`.
- #19: Rework error reporting API
- #17: Removed setup.py and updated poetry in actions
- #17: Removed setup.py and updated poetry in actions

### Documentation

- #22: Update documentation
- #16: Add note on pypi to README

11 changes: 11 additions & 0 deletions doc/changes/unreleased.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# exasol-error-reporting X.Y.Z, released YYYY-MM-DD

Code Name:

## Summary

### Security
### Bugfix
### Feature
### Refactoring
### Documentation
9 changes: 5 additions & 4 deletions doc/dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@

## Test Dependencies

| Dependency | Purpose | License |
|-------------------------------|-----------------------------------|-------------------|
| [Pytest][pytest] | Testing framework | MIT |
| Dependency | Purpose | License |
|------------------|-----------------------------------|---------|
| [Pytest][pytest] | Testing framework | MIT |
| [Prysk][prysk] | Testing framework | GPL |



[python]: https://docs.python.org

[pytest]: https://docs.pytest.org/en/stable/
[prysk]: https://www.prysk.net
Empty file removed doc/design.md
Empty file.
Empty file.
7 changes: 0 additions & 7 deletions doc/developer_guide/developer_guide.md

This file was deleted.

Empty file removed doc/system_requirements.md
Empty file.
139 changes: 14 additions & 125 deletions doc/user_guide/user_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,16 @@ This library lets you define errors with a uniform set of attributes.
Furthermore, the error message is implemented to be parseable,
so that you can extract an error catalog from the code.

## Attributes of Error Builder
## Creating an Error Object

Error messages are built in `ExaError` using the following predefined attributes.
All attributes of the error object except the error code are optional. Thus, the
`ExaError` will still work, even if the other attributes are not provided. Please
keep in mind that error-code should satisfy error-code format
(see [error-code](#error-code)).
Error objects are built using the function `ExaError`.
Please keep in mind that error-code should satisfy the error-code format (see [code](#code)).

Flexibility is provided by introducing placeholder parameters to the error
message in two ways: (1) via the `parameter` attribute and (2) with positional
arguments. Furthermore, placeholders without parameters are filled with <null>.
message.

#### error-code
This attribute should be defined in the error message and provide the following
pattern (`^[FEW]-[[A-Z][A-Z0-9]+(-[A-Z][A-Z0-9]+)*-[0-9]+$`):
#### code
This parameter needs to obey the following format (`^[FEW]-[[A-Z][A-Z0-9]+(-[A-Z][A-Z0-9]+)*-[0-9]+$`):

`severity "-" project-short-tag ["-" module-short-tag] "-" error-number` where,
- _severity_: either F (Failure, not recoverable), or E (Error, recoverable),
Expand All @@ -34,120 +29,14 @@ Examples of valide error codes:
- F-VS-QRW-13

#### message
This attribute includes error description which can be given by either a static
This parameter includes the error description which can be given by either a static
string or a string containing placeholders in double curly brackets. Parameters
of placeholders in the error message can be given as positional arguments
as well as using the `parameter` attribute. The following two usages result in
the same message (`Error message with value`):
- `.message("Error message with {{parameter}}", "value")`
- `.message("Error message with {{parameter}}").parameter("parameter", "value")`
of placeholders in the error message can be provided using the `parameters` parameter.

Furthermore, multiple calls of the `message` method will append the corresponding
message to the previous ones.

#### mitigation
This attribute provides a list of hints on how to fix the error. Its method
structure is the same as for the `message` attribute. Parameters of placeholders
in the mitigations can be given as positional arguments as well as using the
`parameter` attribute. Similar to the `message` method, multiple calls of
the `mitigation` method will append the corresponding mitigation to the
previous ones.
#### mitigations
This parameter provides a list of hints on how to fix the error.
Parameters of placeholders in the mitigations can be given via the `parameters` parameter.

Furthermore, if the only message we can give is to open a ticket, the
`ticket mitigation()` method can be called, which provides a predefined message
about it.

#### parameter
This attribute takes the placeholder name and the parameter value
that will replace this placeholder as argument. It can be used for both message
and mitigations. For example usages, please see the
[Parameters](#Parameters) section.

## Usage

### Simple Messages
```python
ExaError.message_builder("E-TEST-1").message("Something went wrong.")
```
The result of the error message:
```
E-TEST-1: Something went wrong.
```


### Parameters
You can specify placeholders in the message and replace them with
parameters values.

```python
ExaError.message_builder("E-TEST-2")
.message("Unknown input: {{input}}.")
.parameter("input", "unknown", "The illegal user input.")
```
or inline:
```python
ExaError.message_builder("E-TEST-2")
.message("Unknown input: {{input}}.", "unknown")
```
The result of both error messages is same:
```
E-TEST-2: Unknown input: 'unknown'.
```

The optional third argument for `parameter(name, value, description)`
method is used to generate a parameter description for the error-catalog.

The builder automatically quotes parameters (depending on the type of the
parameter). If you don't want that, use the `|uq` suffix in the corresponding
placeholder, as follows:

```python
ExaError.message_builder("E-TEST-2")
.message("Unknown input: {{input|uq}}.")
.parameter("input", "unknown", "The illegal user input.")
```
The result of the error message:
```
E-TEST-2: Unknown input: unknown.
```

### Mitigations
The mitigations describe actions the user can take to resolve the error.
Here is an example of a mitigation definition:

```python
ExaError.message_builder("E-TEST-2")
.message("Not enough space on device.")
.mitigation("Delete something.")
```
The result of the error message:
```
E-TEST-2: Not enough space on device. Delete something.
```

You can use parameters in mitigations too.
```python
ExaError.message_builder("E-TEST-2")
.message("Not enough space on device {{device}}.")
.mitigation("Delete something from {{device}}.")
.parameter("device", "/dev/sda1", "name of the device")
```
The result of the error message:
```
E-TEST-2: Not enough space on device '/dev/sda1'. Delete something from '/dev/sda1'.
```

You can chain `mitigation` definitions if you want to tell the users that there
is more than one solution, as follows:
```python
ExaError.message_builder("E-TEST-2")
.message("Not enough space on device.")
.mitigation("Delete something.")
.mitigation("Create larger partition.")
```
The result of the error message:
```
E-TEST-2: Not enough space on device. Known mitigations:
* Delete something.
* Create larger partition.
```
#### parameters
This argument takes a dictionary of placeholder names and the respective parameter values.
They will be used to replace the placeholders in the mitigations and messages.
15 changes: 9 additions & 6 deletions exasol/error/_error.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class Parameter:
class Error:
def __init__(
self,
name: str,
code: str,
message: str,
mitigations: Union[str, Iterable[str]],
parameters: Dict[str, Union[str, Parameter]],
Expand All @@ -38,26 +38,27 @@ def build_error(code, msg, mitigations, params):

return builder

self._error = build_error(name, message, mitigations, parameters)
self._error = build_error(code, message, mitigations, parameters)

def __str__(self) -> str:
return f"{self._error}"

# TODO: Implement __format__ to conveniently support long and short reporting format
# See also see, Github Issue #28 https://github.com/exasol/error-reporting-python/issues/28


def ExaError(
name: str,
code: str,
message: str,
mitigations: Union[str, List[str]],
parameters: Mapping[str, Union[str, Parameter]],
) -> Error:
"""Create a new ExaError.
The caller is responsible to make sure that the chosen name/id is unique.
The caller is responsible to make sure that the chosen code/id is unique.
Args:
name: unique name/id of the error.
code: unique name/id of the error.
message: the error message itself. It can contain placeholders for parameters.
mitigations: One or multiple mitigations strings. A mitigation can contain placeholders for parameters.
parameters: which will be used for substitute the parameters in the mitigation(s) and the error message.
Expand Down Expand Up @@ -91,5 +92,7 @@ def ExaError(
* Original error message
* Original mitigations
* Original parameters
see also [Github Issue #27](https://github.com/exasol/error-reporting-python/issues/27)
"""
return Error(name, message, mitigations, parameters)
return Error(code, message, mitigations, parameters)
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[tool.poetry]
name = "exasol-error-reporting-python"
name = "exasol-error-reporting"
packages = [
{include = "exasol"},
{include = "exasol_error_reporting_python"}
Expand Down

0 comments on commit 7934de8

Please sign in to comment.