Skip to content

Commit

Permalink
Using RFC as ProblemDetails type #47
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter van den Hout authored and Peter van den Hout committed Apr 25, 2020
1 parent 2774f7b commit cc68834
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,11 @@ protected virtual string MapDetail(TException exception, HttpContext context)
/// </summary>
/// <param name="exception">The exception.</param>
/// <param name="context">The HTTP context.</param>
/// <returns>Returns the URI with the Exception type name ("error:[Type:slug]").</returns>
/// <returns>Returns the Exception.HelpLink or an URI with the Exception type name ("error:[Type:slug]").</returns>
protected virtual string MapType(TException exception, HttpContext context)
{
return new Uri($"error:{MapTitle(exception, context).ToSlug()}").ToString();
var url = exception.HelpLink ?? $"error:{MapTitle(exception, context).ToSlug()}";
return new Uri(url).ToString();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,19 @@ protected virtual string MapDetail(HttpResponse response)
/// Map the ProblemDetails.Type property using the HTTP response.
/// </summary>
/// <param name="response">The HTTP response.</param>
/// <returns>Returns the URI with the HTTP status name ("error:[status:slug]").</returns>
/// <returns>Returns a status code information link (https://tools.ietf.org/html/rfc7231) or the URI with the HTTP status name ("error:[status:slug]").</returns>
protected virtual string MapType(HttpResponse response)
{
return new Uri($"error:{MapTitle(response).ToSlug()}").ToString();
string url = null;
try
{
((HttpStatusCode)response.StatusCode).TryGetLink(out url);
}
catch { }

url ??= $"error:{MapTitle(response).ToSlug()}";

return new Uri(url).ToString();
}
}
}
1 change: 0 additions & 1 deletion src/Opw.HttpExceptions/HttpException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ public override string HelpLink
if (!string.IsNullOrWhiteSpace(_helpLink)) return _helpLink;
if (StatusCode.TryGetLink(out var link)) return link;
return ResponseStatusCodeLink.InternalServerError;

}
set => _helpLink = value;
}
Expand Down
12 changes: 10 additions & 2 deletions src/Opw.HttpExceptions/HttpStatusCodeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,17 @@

namespace Opw.HttpExceptions
{
internal static class HttpStatusCodeExtensions
/// <summary>
/// Extension methods for HttpStatusCode.
/// </summary>
public static class HttpStatusCodeExtensions
{
internal static bool TryGetLink(this HttpStatusCode statusCode, out string link)
/// <summary>
/// Try get a status code information link (https://tools.ietf.org/html/rfc7231).
/// </summary>
/// <param name="statusCode">HTTP status code.</param>
/// <param name="link">The status code information link.</param>
public static bool TryGetLink(this HttpStatusCode statusCode, out string link)
{
try
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,25 @@ public void MapType_Should_ReturnFormattedExceptionName()
result.Should().Be("error:divide-by-zero");
}

[Fact]
public void MapType_Should_ReturnExceptionHelpLink()
{
var helpLink = "https://docs.microsoft.com/en-us/dotnet/api/system.exception.helplink?view=netcore-2.2";
var exception = new ApplicationException { HelpLink = helpLink };
var result = _mapper.MapType(exception, new DefaultHttpContext());

result.Should().Be(helpLink);
}

[Fact]
public void MapType_Should_ReturnExceptionHelpLinkForHttpException()
{
var exception = new BadRequestException();
var result = _mapper.MapType(exception, new DefaultHttpContext());

result.Should().Be(exception.HelpLink);
}

private class ExposeProtectedProblemDetailsExceptionMapper : ProblemDetailsExceptionMapper<Exception>
{
public ExposeProtectedProblemDetailsExceptionMapper(IOptions<HttpExceptionsOptions> options) : base(options) { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,23 @@ public void MapTitle_Should_ReturnHttpStatus()
}

[Fact]
public void MapType_Should_ReturnFormattedHttpStatus()
public void MapType_Should_ReturnResponseStatusCodeLinkUnauthorized()
{
var result = _mapper.MapType(_unauthorizedHttpContext.Response);

result.Should().Be("error:unauthorized");
result.Should().Be(ResponseStatusCodeLink.Unauthorized);
}

[Fact]
public void MapType_Should_ReturnFormattedHttpStatus()
{
var teapotHttpContext = new DefaultHttpContext();
teapotHttpContext.Request.Path = "/api/test/i-am-a-teapot";
teapotHttpContext.Response.StatusCode = 418;

var result = _mapper.MapType(teapotHttpContext.Response);

result.Should().Be("error:418");
}

private class ExposeProtectedProblemDetailsHttpResponseMapper : ProblemDetailsHttpResponseMapper
Expand Down

0 comments on commit cc68834

Please sign in to comment.