Mds.Libraries.CSharp.Server 8.7.0-beta.110456

Mds.Libraries.CSharp.Server

Общий пакет для работы серверов. Содержит в себе множество инструментов от работы с базой, до помощи в обработке запросов.


Обработчики ошибок (IBugReporter)

Пакет содержит в себе инструменты для удобной обработки ошибок на основе интерфейса IBugReporter из пакета Mds.Libraries.CSharp.Abstractions.

Основные классы:

  • SlackBugReporter - отправка отчетов об ошибках в слак.
  • ConsoleBugReporter - вывод отчета об ошибках в консоль.
  • CompositeBugReporter - отправка отчета об ошибках во все каналы.

При добавлении SlackBugReporter и ConsoleBugReporter используются флаги ReporterTypeFlags. Они отвечают за то, в каком виде тот или иной репортер будет зарегистрирован.

ReporterTypeFlags

  • None - Не регистрировать ни в каком виде.
  • Independent - Регистрировать в качестве самостоятельного обработчика ошибок.
  • Channel - Регистрировать в качестве канала для отправки отчетов об ошибках.

Composite

Для доставки отчета об ошибках в несколько каналов используется CompositeBugReporter.

Добавление через Autofac:

public void Add(ContainerBuilder builder)
{
    builder.AddCompositeReporter();
}

Или через IServiceCollection:

public void Add(IServiceCollection services)
{
    services.AddCompositeReporter();
}

Логика его работы подразумевает, что он запрашивает все реализации IExceptionReportChannel в scope и в каждый отправляет уведомление об ошибке.

IExceptionReportChannel

Для реализации функционала, когда каналов доставки отчетом об ошибках много, добавлен интерфейс IExceptionReportChannel. Он аналогичен IBugReporter. Добавлен он для разделения самостоятельных обработчиков и каналов для отправки уведомлений.

Для того, чтобы стандартные репортеры были зарегистрированы в качестве канала для доставки уведомлений, при регистрации необходимо указывать флаг ReporterTypeFlags.Channel.


Slack

Для регистрации обработчика ошибок с отправкой данных в Slack, нужно.

Через Autofac:

public void Add(ContainerBuilder builder)
{
    var hook = "";
    var appName = "";

    builder.AddSlackReporter(hook, appName);
}

Или через IServiceCollection:

public void Add(IServiceCollection services)
{
    var hook = "";
    var appName = "";

    services.AddSlackReporter(hook, appName);
}

Так же можно добавить репортер через SlackBugReporterConfiguration или через реализацию одного из интерфейсов: ISlackBugReporterConfiguration или IExtendedSlackBugReporterConfiguration.

SlackBugReporterConfiguration:

public void Add(ContainerBuilder builder)
{
    var hook = "";
    var appName = "";
    var configuration = new SlackBugReporterConfiguration(hook)
    {
        AppName = appName
    };

    builder.AddSlackReporter(configuration);
}

ISlackBugReporterConfiguration:

public void Add(ContainerBuilder builder)
{
    ISlackBugReporterConfiguration configuration = ...;

    builder.AddSlackReporter(configuration);
}

IExtendedSlackBugReporterConfiguration аналогичный интефейс, только с возможностью расширенной настройки доставки и форматирования сообщений. Таких как канал, имя бота и прочее.

Аналогично через IServiceCollection.

Так же при добавлении репортера есть возможность указать в качестве кого будет добавлен репортер. По умолчанию - Independent:

public void Add(ContainerBuilder builder)
{
    var hook = "";
    var appName = "";

    services.AddSlackReporter(hook, appName, ReporterTypeFlags.Independent | ReporterTypeFlags.Channel);
}

Аналогично через IServiceCollection.


Console

Для вывода в консоль информации об ошибках используется ConsoleBugReporter. Он сделан скорее для разработки, чем для реального применения.

Через Autofac:

public void Add(ContainerBuilder builder)
{
    services.AddConsoleReporter();
}

Аналогично через IServiceCollection.

Так же при добавлении репортера есть возможность указать в качестве кого будет добавлен репортер. По умолчанию - Independent:

public void Add(ContainerBuilder builder)
{
    services.AddConsoleReporter(ReporterTypeFlags.Independent | ReporterTypeFlags.Channel);
}

Аналогично через IServiceCollection.

Sentry

Если в системе подключен Sentry, то его можно подружить с IBugReporter. Для этого надо добавить SentryBugReporter.

Добавление через Autofac:

public void Add(ContainerBuilder builder)
{
    builder.AddSentryReporter();
}

Или через IServiceCollection:

public void Add(IServiceCollection services)
{
    services.AddSentryReporter();
}

Аналогично есть механизм с ReporterTypeFlags:

public void Add(ContainerBuilder builder)
{
    services.AddSentryReporter(ReporterTypeFlags.Independent | ReporterTypeFlags.Channel);
}

Подключение

Подключение репортера подразумевает, что в системе уже настроена интеграция с Sentry.

Обычно для этого надо сделать

Program.cs

public static void Main(string[] args)
{
    return WebHost.CreateDefaultBuilder(args)

                  // Подключение Sentry
                  .UseSentry() // или .UseSentry(option => {})

                  .UseStartup<Startup>();
                  .Build()
}

и

В Mds шаблонах это Configurations.cs, у вас может быть другой файл

public void Configure(IApplicationBuilder app)
{
    app.UseSentryTracing();

    app.UseRouting();
    app.UseEndpoints(endpoints => {});
}

После этого уже можно добавлять SentryBugReporter стандартным способом.


LogicError, LogicErrorsSet и ResultAccessor

У нас есть механизм, чтобы иметь возможность возвращать больше одной ошибки из метода и работать НЕ через Exception.

LogicError

Это контейнер для ошибок. Он изначально затачивался под Api, но его можно использовать для проблем внутри системы.

Он содержит числовой код, строковый код и описание. Желательно заполнять все поля, чтобы в разных частях системы можно было корректно отслеживать ошибки. В коде лучше ориентироваться на код и строковый код. Описание для разработчика или исследования проблемы.

Пример использования

Хранение карты ошибок

public static class Auth
{
    public static LogicError ReachVerificationsLimit { get; } = new (100, "LIMIT_IS_REACHED", "Limit of verifications is reached.");
}

Возврат успешного кода

    private LogicError DoMagic()
    {
        // ...
        return LogicError.Ok;
    }

LogicErrorsSet

Для хранения нескольких LogicError используется LogicErrorsSet. Его задача объединять несколько ошибок.

Удобно использовать, когда ваш метод может вернуть несколько ошибок.

У него есть автоматическое приведение для следующих типов:

  • LogicError - можно вернуть из метода одну ошибку, этого будет достаточно.
  • LogicError[] - можно вернуть из метода набор ошибок от ResultAccessor.Errors

Такая возможность нужна, чтобы можно было делать код методов чище.

Пример использования

private async Task<LogicErrorsSet> DoAndSaveMagicAsync(CancellationToken cancellationToken)
{
    var accessor1 = await _service1.DoMagicAsync(cancellationToken);
    if (accessor1.HasErrors)
    {
        return accessor1.Errors;
    }

    var accessor2 = await _service2.DoMagicAsync(accessor1.Data, cancellationToken);
    if (accessor2.HasErrors)
    {
        return accessor2.Errors;
    }

    await SaveMagicAsync(accessor2.Data, cancellationToken);

    return LogicErrorsSet.Ok;
}

ResultAccessor и ResultAccessorBuilder

Очень часто надо вернуть из сервиса данные или ошибку в ином случае. Чтобы меньше иметь проблем с исключениями.

Для таких сценариев используется ResultAccessor<TResultData>. Он позволяет относительно удобно вернуть результат работы методы или сообщить об ошибках, которые произошли. Своей структурой очень напоминает LogicErrorsSet, но содержит результат работы (Data).

Пример использования

Создавать можно напрямую:

var accessor = new ResultAccessor<string>("John");

Или:

var accessor = new ResultAccessor<string>(LogicErrorsSet.Ok);

Но удобнее всего работать через ResultAccessorBuilder, далее будет пример "почему удобнее?":

var accessor = ResultAccessorBuilder.Empty<string>();

Есть другие методы в ResultAccessorBuilder:

ResultAccessor.From<string>("John");
ResultAccessor.From<string>(LogicError.Ok);
ResultAccessor.From<string>(new [] { LogicError.Ok });
ResultAccessor.From<string>(LogicErrorsSet.Ok);

Основной пример использования, когда мы сразу создаем accessor и дальше используем его для формирования результата работы метода:

ResultAccessor<int> Parse(HttpResponse response)
{
    // ResultAccessorBuilder позволяет нам зафиксировать Generic один раз и дальше уже работать, как нам удобно
    var accessor = ResultAccessorBuilder.Empty<int>();

    if (TryParse(response, out var result) is false)
    {
        return accessor.With(new LogicError(-1, message: "Problem with parsing."));
    }

    return accessor.With(result);
}

Showing the top 20 packages that depend on Mds.Libraries.CSharp.Server.

Packages Downloads
Mds.Cdn.Api.Client
Апи клиент для работы с Mds.Cdn.
2
Mds.Cdn.Sdk
Апи клиент для работы с Mds.Cdn.
1
Mds.Cdn.Sdk
Апи клиент для работы с Mds.Cdn.
2
Mds.Libraries.CSharp.ChangesBus
Пакет для интеграции шины для обновления сущностей.
1
Mds.Libraries.CSharp.ChangesBus
Пакет для интеграции шины для обновления сущностей.
2
Mds.Libraries.CSharp.MutexContainer
Пакет удобное работы для синхронизации работы над одной сущностью.
1

Version Downloads Last updated
9.0.1 3 02/28/2026
9.0.0 1 02/28/2026
9.0.0-beta.122950 1 02/28/2026
8.7.1 1 02/28/2026
8.7.0 1 02/28/2026
8.7.0-beta.110592 1 02/28/2026
8.7.0-beta.110590 1 02/28/2026
8.7.0-beta.110456 1 02/28/2026
8.7.0-beta.110431 1 02/28/2026
8.7.0-beta.110426 1 02/28/2026
8.7.0-beta.110424 1 02/28/2026
8.7.0-beta.110379 1 02/28/2026
8.7.0-beta.110373 1 02/28/2026
8.7.0-beta.110349 1 02/28/2026
8.7.0-beta.110214 1 02/28/2026
8.7.0-beta.110212 1 02/28/2026
8.7.0-beta.110209 1 02/28/2026
8.7.0-beta.110196 1 02/28/2026
8.7.0-beta.103522 1 02/28/2026
8.7.0-beta.103519 1 02/28/2026
8.7.0-beta.103510 1 02/28/2026
8.7.0-beta.103506 1 02/28/2026
8.7.0-beta.103502 1 02/28/2026
8.6.2 1 02/28/2026
8.6.0 1 02/28/2026
8.6.0-beta.105697 1 02/28/2026
8.6.0-beta.88070 1 02/28/2026
8.5.0 1 02/28/2026
8.5.0-beta.88057 1 02/28/2026
8.4.1 1 02/28/2026
8.4.1-beta.105685 1 02/28/2026
8.4.1-beta.86789 1 02/28/2026
8.4.0 1 02/28/2026
8.3.1 1 02/28/2026
8.3.0 1 02/28/2026
8.3.0-beta.65967 1 02/28/2026
8.3.0-beta.65962 1 02/28/2026
8.2.1 1 02/28/2026
8.2.0 1 02/28/2026
8.1.0 1 02/28/2026
8.0.5 1 02/28/2026
8.0.3 1 02/28/2026
8.0.3-beta.14759 1 02/28/2026
8.0.2 1 02/28/2026
8.0.1 1 02/28/2026
8.0.0 1 02/28/2026
7.0.1 1 02/28/2026
7.0.1-beta.6491 1 02/28/2026
7.0.1-beta.5494 1 02/28/2026
7.0.0-beta.2117 1 02/28/2026
6.6.0 1 02/28/2026
6.4.4 1 02/28/2026
6.4.0 1 02/28/2026
6.2.1 1 02/28/2026