• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ThreeMammals / Ocelot / 23302213965

19 Mar 2026 03:19PM UTC coverage: 91.219% (-1.3%) from 92.49%
23302213965

Pull #2369

github

web-flow
Merge 7f6f01146 into 086c7b15c
Pull Request #2369: Pre-Release 25.0 aka Beta 2

8404 of 9213 relevant lines covered (91.22%)

2131.48 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

55.74
src/Ocelot/Errors/Middleware/ExceptionHandlerMiddleware.cs
1
using Microsoft.AspNetCore.Http;
2
using Ocelot.Configuration;
3
using Ocelot.Infrastructure.Extensions;
4
using Ocelot.Infrastructure.RequestData;
5
using Ocelot.Logging;
6
using Ocelot.Middleware;
7

8
namespace Ocelot.Errors.Middleware;
9

10
/// <summary>
11
/// Catches all unhandled exceptions thrown by middleware, logs and returns a 500.
12
/// </summary>
13
public class ExceptionHandlerMiddleware : OcelotMiddleware
14
{
15
    private readonly RequestDelegate _next;
16
    private readonly IRequestScopedDataRepository _repo;
17

18
    public ExceptionHandlerMiddleware(RequestDelegate next,
19
        IOcelotLoggerFactory loggerFactory,
20
        IRequestScopedDataRepository repo)
21
            : base(loggerFactory.CreateLogger<ExceptionHandlerMiddleware>())
8✔
22
    {
8✔
23
        _next = next;
8✔
24
        _repo = repo;
8✔
25
    }
8✔
26

27
    public async Task Invoke(HttpContext context)
28
    {
6✔
29
        try
30
        {
6✔
31
            context.RequestAborted.ThrowIfCancellationRequested();
6✔
32

33
            var configuration = context.Items.IInternalConfiguration();
6✔
34
            TrySetGlobalRequestId(context, configuration);
6✔
35

36
            Logger.LogDebug("Ocelot pipeline started");
4✔
37
            await _next.Invoke(context);
4✔
38
        }
3✔
39
        catch (OperationCanceledException e) when (context.RequestAborted.IsCancellationRequested)
×
40
        {
×
41
            Logger.LogDebug("Operation canceled");
×
42
            Logger.LogWarning(() => CreateMessage(context, e, true));
×
43
            if (!context.Response.HasStarted)
×
44
            {
×
45
                context.Response.StatusCode = StatusCodes.Status499ClientClosedRequest; // custom Ocelot code
×
46
            }
×
47
        }
×
48
        catch (Exception e)
3✔
49
        {
3✔
50
            Logger.LogDebug("Error calling middleware");
3✔
51
            Logger.LogError(() => CreateMessage(context, e), e);
3✔
52
            if (!context.Response.HasStarted)
3✔
53
            {
3✔
54
                context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
3✔
55
            }
3✔
56
        }
3✔
57
        finally
58
        {
6✔
59
            Logger.LogDebug("Ocelot pipeline finished");
6✔
60
        }
6✔
61
    }
6✔
62

63
    private void TrySetGlobalRequestId(HttpContext context, IInternalConfiguration configuration)
64
    {
6✔
65
        var key = configuration.RequestId;
6✔
66
        if (!string.IsNullOrEmpty(key) && context.Request.Headers.TryGetValue(key, out var upstreamRequestIds))
4✔
67
        {
1✔
68
            context.TraceIdentifier = upstreamRequestIds.First();
1✔
69
        }
1✔
70

71
        _repo.Add(nameof(IInternalConfiguration.RequestId), context.TraceIdentifier);
4✔
72
    }
4✔
73

74
    private static string CreateMessage(HttpContext context, Exception e, bool includeException = false)
75
    {
×
76
        var original = e;
×
77
        var builder = new StringBuilder()
×
78
            .AppendLine($"{e.GetType().Name} caught in global error handler!");
×
79
        int total = 0;
×
80
        while (e.InnerException != null)
×
81
        {
×
82
            builder.AppendLine(e.InnerException.ToString());
×
83
            e = e.InnerException;
×
84
            total++;
×
85
        }
×
86

87
        builder.Append($"DONE reporting of a total {total} inner exception{total.Plural()} for request {context.TraceIdentifier} of the original {original.GetType().Name} below ->");
×
88
        if (includeException)
×
89
        {
×
90
            builder.Append(Environment.NewLine + original.ToString());
×
91
        }
×
92

93
        return builder.ToString();
×
94
    }
×
95
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc