Хорошее, подробное исключение — это мощный инструмент, который поможет вам найти и устранить проблему.
Поэтому стоит добавить более подробную информацию об исключениях.
Один из способов — добавить дополнительную информацию в тело сообщения об исключении.
Как в коде ниже.
Но при таком подходе сложно создавать сообщения.try { return await _ordersRepository.Get(id, cancellationToken); } catch (Exception exception) { throw new Exception($"Unable to get order info, user {userName}, order id {id}", exception); }
И небезопасно: пользователю может быть отправлено сообщение в тех случаях, когда исключение не было обработано корректно.
Нам следует избегать отправки пользователю такой информации, как идентификаторы.
Все, что нужно для исправления ошибки, — это зарегистрировать дополнительную информацию и информацию об исходном исключении на стороне сервера.
Другой подход — создать собственное исключение с определенными свойствами.
Но создать множество классов исключений уже достаточно сложно, и основная проблема — настройка логирования свойств этих классов.
Класс исключений .
NET Framework имеет свойство Данные , который уже обеспечивает хранение дополнительной информации в виде набора заданных пар ключ-значение.
Поскольку это свойство базового класса, я уверен, что вы сможете настроить регистратор.
В наших примерах ниже мы будем использовать NLog, который довольно легко настроить.
Избегать ключевой конфликт и обработать ошибку наиболее эффективным способом, я советую вам также создать собственное исключение.
Половина классов исключений .
NET Framework имеют свойства, которые не регистрируются — вы можете добавить эти данные в свойство Exception.Data вашего нового исключения.
Свойство Внутреннее исключение будет содержать ссылку на исходное исключение.
Код ниже демонстрирует, как использовать свойство Exception.Data. try
{
return await _ordersRepository.Get(id, cancellationToken);
}
catch (Exception exception)
{
const string message = "Unable to get order info";
var yourException = new YourAppException(message, exception);
yourException.Data[nameof(userName)] = userName;
yourException.Data[nameof(id)] = id;
throw yourException;
}
Упс.
Похоже, мы добавили больше кода, но мы можем это исправить, создав расширения, которые включают шаблон интерфейса Fluent. В примере ниже показано, как сделать код более читабельным и простым в использовании.
try
{
return await _ordersRepository.Get(id, cancellationToken);
}
catch (Exception exception)
{
throw exception.With("Unable to get order info")
.
DetailData(nameof(userName), userName) .
DetailData(nameof(id), id);
}
Давайте рассмотрим пример настройки Макет Нлога для регистрации свойства Exception.Data. ${shortdate} ${time} [${level:uppercase=true}]: ${message:withException=true}${when:when=length('${exception:format=Data}')>0:Inner=${newline}--- Exception Data ---${newline}${exception:format=Data:exceptionDataSeparator=,\r\n}}
Как это выглядит в консоли.
Этот пример отлично работает, если вы добавляете простые структуры: NLog вызывает ToString() для записи значений в цели.
Следовательно, мы можем правильно закладывать объекты только в том случае, если они правильно переопределяют метод ToString().
Но переопределить ToString для всех классов практически невозможно.
Самый простой способ представить объект в виде строки — сериализовать его в JSON. Код ниже добавляет класс C#, который делает это.
/// <summary>
/// Defines a value/json pair to represent an exception data value as JSON
/// </summary>
public record ExceptionDataEntry
{
private static readonly JsonSerializerOptions SerializerOptions = new()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
Converters = {new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)},
WriteIndented = true
};
private ExceptionDataEntry(in object value, in string json)
{
Value = value;
Json = json;
}
public object Value { get; }
public string Json { get; }
public static ExceptionDataEntry FromValue(in object value)
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
var json = JsonSerializer.Serialize(value, SerializerOptions);
return new ExceptionDataEntry(value, json);
}
/// <summary>
/// Represents an exception data value as JSON
/// </summary>
/// <returns></returns>
public override string ToString()
{
return Json;
}
}
И этот код добавляет расширение.
public static YourAppException DetailData(this YourAppException exception, in string key, in object value)
{
try
{
exception.Data[key] = ExceptionDataEntry.FromValue(value);
}
catch
{
// ignored, because we use it inside another exception catch block
// so, we should avoid throwing a new exception to keep the original exception
}
return exception;
}
Как это будет выглядеть в консоли в нашем примере.
Я надеюсь, что этот подход к использованию Exception.Data для регистрации дополнительной информации поможет вам в поддержке приложений.
Если у вас есть идеи, как улучшить предложенный подход, пишите в комментариях.
Спасибо =) Теги: #программирование #C++ #мониторинг #ведение журнала #.
NET #отладка #обработка ошибок #журналы #ведение журнала #Exception #NLog #Exception
-
Как Настроить Ваш Сайт Для Увеличения Продаж
19 Oct, 24 -
В Мошенничество Нельзя Верить
19 Oct, 24 -
Июнь Зи
19 Oct, 24 -
Обучение По Iis 7.0 В Москве
19 Oct, 24 -
Fast Предлагает Рекламу Без Посредников
19 Oct, 24