# Veramo Error Handling Design
# Design Decisions
### Improve the MessageHandler Chain to make errors more transparent
We will split the exist message handler modules to provide two distinct methods.
1. Message Parser:
Every Module in the Message Handler Chain needs to expose a Parser. A Message Parser is a required method that MUST NOT fail and determines if an incoming payload is a) relevant b) tries (only if simple) extract and map assoicated data into a parsed format. The message parser can **ONLY** return two things:
a) The parsed message that will be the input for the message handler
b) `undefined` indicating that the Message Handler **IS NOT** responsible for the given input
All Logs within the **Message Parser** are **DEBUG**, since the they will be invoked for EVERY Message
2. Message Handler:
Message Handlers are ONLY executed if the associated parser did not return `undefined`. Since the Message Parser already determined that the overall Handler is responsible, the Message Handler implementation **MAY** fail. Failures are expressed by thrown errors or `undefined` return types.
### Integrate Event Handling to Message Handler Chain
Currently, integrators have little possibility to hook into the process of the Message Handler. Therefore we would like to emit specific Message Handler events when configured Parsers or Handlers are starting or finishing their execution.
Furthermore, we like to introduce specific events at the beginngin and end of the overall message handler chain in order to decouple data persistence from the message handler chain. (e.g. a parsed message get's persisted when an given Event is emitted)
### Introduce a string convention for error messages emitted in Veramo
- We use `error.prototype.message` to transport a unique error identifier and english error message
- Error identifier and error message a delimited by a `:`, e.g. `example_identifier: This is a test error message`
- Errors reaching OpenAPI will transform into HTTP Status Code `400` and payload:
```
{
"error": ${error.message}
}
```
### MessageHandling (Chains) are (initally) only used for incoming (DID-Comm Messages)
Specifically, we do not consider the Message Handler Chain something that should interfaced by integrators at the moment. If integrators want to chain specific logic within veramo they should manually integrate multiple agent methods (or associated libraries, e.g. generic JWT verify). That requires veramo to expose relevant methods to integrators that might be missing at the moment.
# Previous Meeting Notes
## Considerations
The following elements need to be considered for error handling within Veramo:
- Errors that are throw out of base libraries (e.g. did-jwt)
- Native Errors within Veramo
- Mapping / Exposing Errors within OpenAPI
- Logging for implicitly caught errors
- Message Handling when using DIDComm Endpoint.
## Design
- Option A: There exists a dedicated veramo package "errors" that contains the unique string identifiers that can be thrown within Veramo.
- Option B: Veramo packages have define error strings within the package itself according to an convention (e.g. error.ts). This will not detect duplicates. (Maybe higher level checks / CI can be added for this)
- Base Library Errors (where surrouned with try/catch) are wrapped into a specific error type (e.g. DID_JWT). Note: In the end it might be hard to determine which library threw the actual error (especially on multi-statement try/catches)
- Update Message Handler Architecture to not silently fail if `return message` is never called. Log errors in the message handler chain (thrown, or unexpected return type (undefined/null)).
- Message Parser/Handler architecture plugin:
- responsbible true/false (MessageParser) - simple, sets type, does not throw. Set metadata:
- LOGGING: Handler was active / handler was not active.
- handle (MessageHandler) - complex, can throw
- LOGGING: Can log specific error.
- Message Handler Chain:
- Problem: Static Chain is retrictive. Parsers/Handlers are called that we could already exclude on previous handlers.
- Alternative to two-passed message interpretation: Event-based System.
- Reactive Model
- EventHandlers emit new Events that can be picked up by any numbers
- Hard to test (marble testing)
- Remove Message peristence out of Message Handler base code and create a specific event for parsed message persistance.
- Errors reaching OpenAPI will transform into HTTP Status Code `400` and payload:
```
{
"code": ERROR_CODE_STRING
}
```
- We use `error.prototype.message` to transport `ERROR_CODE_STRING` and message
- `ERROR_CODE_STRING` contains an error code an english human readable error description. If no `code` can be extracted in regard to the convention, the error_code is assumed `UNKNOWN`
Problem Statement:
1. Verify stuff without going through Message Handler
2. If they go through the message handler they don't have proper errors.
--> Two step message handler
--> More descriptive error message
--> At the end of the message handler chain we pass a list of all errors associated with the respective handlers.
###### tags: `api design`