Design pattern for including errors with return values

I am writing an add-in for other software through my API. The classes returned by the API can only be accessed through its own software and API. Therefore, I write my own standalone POCO / DTO objects that map to API classes. I am working on a function that will be read in its own file and returns a collection of these POCO objects that I can steal elsewhere. I am currently using JSON.NET to serialize these classes to JSON, if that matters.

For example, I may have such a DTO

public class MyPersonDTO { public string Name {get; set;} public string Age {get; set;} public string Address {get; set;} } 

.. and a method like this to read native โ€œFacesโ€ into my DTO objects

 public static class MyDocReader { public static IList<MyPersonDTO> GetPersons(NativeDocument doc) { //Code to read Persons from doc and return MyPersonDTOs } } 

I have a unit test setup with a test file, however, unexpected problems occur when starting my export to other files. Sometimes native objects will have unexpected values, or the API will not have errors that throw exceptions when there is no reason for.

Currently, when something โ€œexceptionalโ€ happens, I just log the exception and the export fails. But I decided it was better to export, that I could, and write errors somewhere.

The easiest option is to simply register and catch the exceptions and return what I can, but then there would be no way to find out the call code when the problem occurred.

One of the options I'm considering is returning an error dictionary as a separate out parameter. The key identifies a property that cannot be read, and the value will contain exception / error information.

 public static class MyDocReader { public static IList<MyPersonDTO> persons GetPersons(NativeDocument doc, out IDictionary<string, string> errors) { //Code to read persons from doc } } 

As an alternative, I also considered the possibility of simply storing errors in the return object itself. This inflates the size of my object, but has the added benefit of storing errors directly with my objects. Therefore, if someone is exporting an error message, I donโ€™t have to worry about tracking the correct log file on my computer.

 public class MyPersonDTO { public string Name {get; set;} public string Age {get; set;} public string Address {get; set;} public IDictionary<string, string> Errors {get; set;} } 

How is this usually handled? Is there another option for reporting errors along with return values โ€‹โ€‹that I am not considering?

+5
source share
2 answers

Instead of returning errors as part of entities, you can wrap the result with an answer or an answer. Errors can be part of the response message instead of objects.

The advantage of this is that the objects are clean.

The disadvantage is that it will be more difficult to correlate errors with damaged objects / attributes.

When sending batches of objects, this drawback can be a big problem. When the API is more focused on a single entity, it does not matter much.

+4
source

Basically, if something goes wrong in the API (which cannot be repaired), the calling code should know that an exception has occurred. Therefore, he may have a strategy to solve this problem.

Therefore, the approach that comes to my mind depends on the same philosophy -

1> Define your own exception. Say an IncompleteReadException . This exception must have the IList<MyPersonDTO> property to hold records read until an exception occurs.

 public class IncompleteReadException : Exception { IList<MyPersonDTO> RecordsRead { get; private set; } public IncompleteReadException(string message, IList<MyPersonDTO> recordsRead, Exception innerException) : base(message,innerException) { this.RecordsRead = recordsRead; } } 

2> When an exception occurs while reading, you can catch the original exception, wrap the original exception in this and throw an IncompleteReadException

This will allow calling the code (application code) in order to have a strategy for solving the situation when incomplete data is read.

+1
source

Source: https://habr.com/ru/post/1234552/


All Articles