tgstation-server  4.4.0
The /tg/station 13 server suite
ApplicationBuilderExtensions.cs
Go to the documentation of this file.
1 using Microsoft.AspNetCore.Builder;
2 using Microsoft.AspNetCore.Http;
3 using Microsoft.AspNetCore.Mvc;
4 using Microsoft.EntityFrameworkCore;
5 using Microsoft.Extensions.DependencyInjection;
6 using Microsoft.Extensions.Logging;
7 using System;
8 using System.Globalization;
9 using System.Net;
11 
12 namespace Tgstation.Server.Host.Extensions
13 {
18  {
24  static ILogger GetLogger(HttpContext httpContext) => httpContext.RequestServices.GetRequiredService<ILoggerFactory>().CreateLogger(typeof(ApplicationBuilderExtensions));
25 
30  public static void UseDbConflictHandling(this IApplicationBuilder applicationBuilder)
31  {
32  if (applicationBuilder == null)
33  throw new ArgumentNullException(nameof(applicationBuilder));
34  applicationBuilder.Use(async (context, next) =>
35  {
36  var logger = GetLogger(context);
37  try
38  {
39  await next().ConfigureAwait(false);
40  }
41  catch (DbUpdateException e)
42  {
43  if (e.InnerException is OperationCanceledException)
44  {
45  logger.LogTrace("Rethrowing DbUpdateException as OperationCanceledException: {0}", e);
46  throw e.InnerException;
47  }
48 
49  logger.LogDebug("Database conflict: {0}", e.Message);
50  await new ConflictObjectResult(new ErrorMessage(ErrorCode.DatabaseIntegrityConflict)
51  {
52  AdditionalData = String.Format(CultureInfo.InvariantCulture, (e.InnerException ?? e).Message)
53  }).ExecuteResultAsync(new ActionContext
54  {
55  HttpContext = context
56  }).ConfigureAwait(false);
57  }
58  });
59  }
60 
65  public static void UseCancelledRequestSuppression(this IApplicationBuilder applicationBuilder)
66  {
67  if (applicationBuilder == null)
68  throw new ArgumentNullException(nameof(applicationBuilder));
69  applicationBuilder.Use(async (context, next) =>
70  {
71  var logger = GetLogger(context);
72  try
73  {
74  await next().ConfigureAwait(false);
75  }
76  catch (OperationCanceledException)
77  {
78  logger.LogDebug("Request cancelled!");
79  }
80  });
81  }
82 
87  public static void UseServerErrorHandling(this IApplicationBuilder applicationBuilder)
88  {
89  if (applicationBuilder == null)
90  throw new ArgumentNullException(nameof(applicationBuilder));
91  applicationBuilder.Use(async (context, next) =>
92  {
93  var logger = GetLogger(context);
94  try
95  {
96  await next().ConfigureAwait(false);
97  }
98  catch (Exception e)
99  {
100  logger.LogError("Failed request: {0}", e);
101  await new ObjectResult(
102  new ErrorMessage(ErrorCode.InternalServerError)
103  {
104  AdditionalData = e.ToString()
105  })
106  {
107  StatusCode = (int)HttpStatusCode.InternalServerError
108  }
109  .ExecuteResultAsync(new ActionContext
110  {
111  HttpContext = context
112  }).ConfigureAwait(false);
113  }
114  });
115  }
116  }
117 }
static void UseDbConflictHandling(this IApplicationBuilder applicationBuilder)
Return a ConflictObjectResult for DbUpdateExceptions
ErrorCode
Types of ErrorMessages that the API may return.
Definition: ErrorCode.cs:10
static void UseServerErrorHandling(this IApplicationBuilder applicationBuilder)
Suppress all in flight exceptions with error 500.
static void UseCancelledRequestSuppression(this IApplicationBuilder applicationBuilder)
Suppress TaskCanceledException warnings when a user aborts a request
Represents an error message returned by the server
Definition: ErrorMessage.cs:9