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

ThreeMammals / Ocelot / 26241073880

21 May 2026 05:06PM UTC coverage: 95.327% (+0.6%) from 94.721%
26241073880

push

github

raman-m
Ref SDK 10.0.300 (Runtime 10.0.8) to release Ocelot v25 beta 3 and Ocelot.Testing v25 beta 8+ (#2389)

* Prepare to release Ocelot.Testing v25.0.0-beta.8 package
* Bump all packages to the latest versions, including .NET SDK 10.0.203 (Runtime 10.0.7) released April 21, 2026
* Migrate unit testing from VSTest framework to Microsoft.Testing.Platform
* Do not use 'Cake Build' step in PR workflow, use plain dotnet scripting instead
* Fix "Unit Tests" step in PR workflow
* Rename job to "build" since it's not Cake anymore
* Suppress non-zero result and check test running status
* Update "Acceptance Tests" step
* Don't collect Coverlet code coverage data in "Acceptance Tests" step
* Update prepare-coveralls.sh
* Prepare Coveralls script v2
* Prepare Coveralls script v3
* Prepare Coveralls script v4
* Prepare Coveralls script v5 -> Add 2nd BUILD_CONFIGURATION argument
* Upgrade to SDK 10.0.300 aka Runtime 10.0.8
* Update samples
* Update workflows: prefer plain dotnet scripting over Cake Build

6752 of 7083 relevant lines covered (95.33%)

2730.81 hits per line

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

55.74
src/Ocelot/Errors/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;
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>())
12✔
22
    {
12✔
23
        _next = next;
12✔
24
        _repo = repo;
12✔
25
    }
12✔
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