< Summary

Information
Class: Despesas.GlobalException.CustomExceptions.Core.EfCoreExceptionHandler
Assembly: Despesas.GlobalException
File(s): /src/Despesas.GlobalException/CustomExceptions/Core/EfCoreExceptionHandler.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 39
Coverable lines: 39
Total lines: 72
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 14
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
HandleAsync()0%210140%
WriteResponseAsync()100%210%

File(s)

/src/Despesas.GlobalException/CustomExceptions/Core/EfCoreExceptionHandler.cs

#LineLine coverage
 1using Microsoft.AspNetCore.Http;
 2using Microsoft.EntityFrameworkCore;
 3using Microsoft.Extensions.Logging;
 4using System.Text.Json;
 5
 6namespace Despesas.GlobalException.CustomExceptions.Core;
 7
 8public static class EfCoreExceptionHandler
 9{
 10    public static async Task<bool> HandleAsync(HttpContext context, Exception ex, ILogger logger)
 011    {
 012        switch (ex)
 13        {
 14            case DbUpdateConcurrencyException concurrencyEx:
 015                logger.LogError(concurrencyEx, "Conflito de concorrência no banco de dados");
 016                await WriteResponseAsync(context, StatusCodes.Status409Conflict,
 017                    "Erro ao atualizar o registro. Pode ter sido alterado ou removido por outro usuário.");
 018                return true;
 19
 20            case DbUpdateException dbEx:
 021                logger.LogError(dbEx, "Erro ao salvar alterações no banco de dados");
 22
 23                // 🔹 Se for violação de chave estrangeira (FK constraint)
 024                if (dbEx.InnerException?.Message.Contains("FOREIGN KEY", StringComparison.OrdinalIgnoreCase) == true)
 025                {
 026                    await WriteResponseAsync(context, StatusCodes.Status400BadRequest,
 027                        "Não é possível excluir este registro, pois existem dados vinculados.");
 028                    return true;
 29                }
 30
 031                await WriteResponseAsync(context, StatusCodes.Status500InternalServerError,
 032                    "Erro ao acessar os dados. Tente novamente mais tarde.");
 033                return true;
 34
 35            case InvalidOperationException invOpEx:
 036                logger.LogError(invOpEx, "Registro não encontrado ou operação inválida no repositório");
 037                await WriteResponseAsync(context, StatusCodes.Status404NotFound,
 038                    "Registro não encontrado ou operação inválida.");
 039                return true;
 40
 41            case NullReferenceException nullEx:
 042                logger.LogError(nullEx, "Referência nula detectada");
 043                await WriteResponseAsync(context, StatusCodes.Status500InternalServerError,
 044                    "Erro interno inesperado.");
 045                return true;
 46
 47            case ArgumentException argEx:
 048                logger.LogError(argEx, "Erro de argumento inválido");
 049                await WriteResponseAsync(context, StatusCodes.Status400BadRequest,
 050                    argEx.Message);
 051                return true;
 52
 53            default:
 54                // Qualquer outra exceção -> deixa o middleware global tratar
 055                return false;
 56        }
 057    }
 58
 59    private static async Task WriteResponseAsync(HttpContext context, int statusCode, string message)
 060    {
 061        context.Response.ContentType = "application/json";
 062        context.Response.StatusCode = statusCode;
 63
 064        var response = new
 065        {
 066            success = false,
 067            error = message
 068        };
 69
 070        await context.Response.WriteAsync(JsonSerializer.Serialize(response));
 071    }
 72}

Methods/Properties

HandleAsync()
WriteResponseAsync()