Skip to content

Commit f39095d

Browse files
authored
Merge pull request #9 from isaacnborges/feature/unauthorized
Add support to UnauthorizedException
2 parents eee0b4a + ffbb38f commit f39095d

File tree

10 files changed

+144
-1
lines changed

10 files changed

+144
-1
lines changed

README-nuget.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ The custom middleware supports the following **Exceptions**:
8484
Exception Status code description Status code
8585
--------------------- ----------------------- -----------
8686
DomainException BadRequest 400
87+
UnauthorizedException Unauthorized 401
8788
CannotAccessException Forbidden 403
8889
NotFoundException NotFound 404
8990
Exception InternalServerError 500
@@ -109,6 +110,7 @@ public class InvalidStateException : DomainException
109110
#### Throw exceptions
110111
```c#
111112
throw new InvalidStateException("Custom domain exception message");
113+
throw new UnauthorizedException("Custom unauthorized exception message");
112114
throw new CannotAccessException("Custom cannot access exception message");
113115
throw new NotFoundException("Custom not found exception message");
114116
throw new Exception("Custom exception message");

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ The custom middleware supports the following **Exceptions**:
8484
| Exception | Status code description | Status code |
8585
|-----------------------|-------------------------|:-----------:|
8686
| DomainException | BadRequest | 400 |
87+
| UnauthorizedException | Unauthorized | 401 |
8788
| CannotAccessException | Forbidden | 403 |
8889
| NotFoundException | NotFound | 404 |
8990
| Exception | InternalServerError | 500 |
@@ -108,6 +109,7 @@ public class InvalidStateException : DomainException
108109
#### Throw exceptions
109110
```c#
110111
throw new InvalidStateException("Custom domain exception message");
112+
throw new UnauthorizedException("Custom unauthorized exception message");
111113
throw new CannotAccessException("Custom cannot access exception message");
112114
throw new NotFoundException("Custom not found exception message");
113115
throw new Exception("Custom exception message");

samples/CustomExceptionMiddleware.WebAppTest/Controllers/CustomerController.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ public IActionResult GetDomain([FromQuery] bool returnCustomer = false)
2727
return Ok(result);
2828
}
2929

30+
[HttpGet("unauthorized")]
31+
public IActionResult GetUnauthorized([FromQuery] bool returnCustomer = false)
32+
{
33+
var result = _customerService.GetUnauthorizedException(returnCustomer);
34+
return Ok(result);
35+
}
36+
3037
[HttpGet("cannot-access")]
3138
public IActionResult GetCannotAccess([FromQuery] bool returnCustomer = false)
3239
{

samples/CustomExceptionMiddleware.WebAppTest/CustomerService.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ public IEnumerable<Customer> GetDomainException(bool returnCustomers)
2020
throw new InvalidStateException("Custom domain exception message");
2121
}
2222

23+
public IEnumerable<Customer> GetUnauthorizedException(bool returnCustomers)
24+
{
25+
if (returnCustomers)
26+
return GetCustomers();
27+
28+
throw new UnauthorizedException("Custom unauthorized exception message");
29+
}
30+
2331
public IEnumerable<Customer> GetCannotAccessException(bool returnCustomers)
2432
{
2533
if (returnCustomers)

samples/CustomExceptionMiddleware.WebAppTest/ICustomerService.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ public interface ICustomerService
66
{
77
IEnumerable<Customer> Get(int customersCount);
88
IEnumerable<Customer> GetDomainException(bool returnCustomers);
9+
IEnumerable<Customer> GetUnauthorizedException(bool returnCustomers);
910
IEnumerable<Customer> GetCannotAccessException(bool returnCustomers);
1011
IEnumerable<Customer> GetNotFoundException(bool returnCustomers);
1112
IEnumerable<Customer> GetException(bool returnCustomers);

src/CustomExceptionMiddleware.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ public async Task InvokeAsync(HttpContext httpContext)
5555
{
5656
await HandleDomainException(httpContext, ex);
5757
}
58+
catch (UnauthorizedException ex) when (NotContainExceptionAttribute(httpContext))
59+
{
60+
await HandleUnauthorizedException(httpContext, ex);
61+
}
5862
catch (CannotAccessException ex) when (NotContainExceptionAttribute(httpContext))
5963
{
6064
await HandleCannotAccessException(httpContext, ex);
@@ -74,6 +78,11 @@ private async Task HandleDomainException(HttpContext httpContext, DomainExceptio
7478
await HandleException(httpContext, exception, HttpStatusCode.BadRequest);
7579
}
7680

81+
private async Task HandleUnauthorizedException(HttpContext httpContext, UnauthorizedException exception)
82+
{
83+
await HandleException(httpContext, exception, HttpStatusCode.Unauthorized);
84+
}
85+
7786
private async Task HandleCannotAccessException(HttpContext httpContext, CannotAccessException exception)
7887
{
7988
await HandleException(httpContext, exception, HttpStatusCode.Forbidden);

src/CustomExceptionMiddleware.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFrameworks>netstandard2.0;netstandard2.1;</TargetFrameworks>
5-
<Version>1.2.0</Version>
5+
<Version>1.2.1</Version>
66
<Authors>Isaac Nunes Borges</Authors>
77
<Company>isaacnborges</Company>
88
<LangVersion>10.0</LangVersion>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System;
2+
using System.Runtime.Serialization;
3+
4+
namespace CustomExceptionMiddleware.CustomExceptions
5+
{
6+
[Serializable]
7+
public class UnauthorizedException : CustomException
8+
{
9+
public UnauthorizedException()
10+
{ }
11+
12+
public UnauthorizedException(string message) : base(message)
13+
{ }
14+
15+
public UnauthorizedException(string message, Exception innerException) : base(message, innerException)
16+
{ }
17+
18+
public UnauthorizedException(string message, string exceptionType) : base(message)
19+
{
20+
ExceptionType = exceptionType;
21+
}
22+
23+
public UnauthorizedException(string message, string exceptionType, Exception innerException) : base(message, innerException)
24+
{
25+
ExceptionType = exceptionType;
26+
}
27+
28+
protected UnauthorizedException(SerializationInfo info, StreamingContext context) : base(info, context)
29+
{ }
30+
}
31+
}

tests/CustomExceptionMiddlewareWebAppTests.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,22 @@ public async Task GetAsync_ThrowDomainException_ShouldReturnBadRequest()
5656
responseContent.Type.Should().Be(ValidationErrors);
5757
}
5858

59+
[Fact(DisplayName = "Should return unauthorized and throw an unauthorized exception")]
60+
public async Task GetAsync_ThrowUnauthorizedException_ShouldUnauthorized()
61+
{
62+
// Arrange
63+
_url += "/unauthorized";
64+
65+
// Act
66+
var response = await _client.GetAsync(_url);
67+
68+
// Assert
69+
response.Should().Be401Unauthorized();
70+
var responseContent = await response.Content.ReadAsAsync<CustomErrorResponse>();
71+
responseContent.Error.Msg.Should().Be("Custom unauthorized exception message");
72+
responseContent.Type.Should().Be(ValidationErrors);
73+
}
74+
5975
[Fact(DisplayName = "Should return forbidden and throw a cannot access exception")]
6076
public async Task GetAsync_ThrowCannotAccessException_ShouldReturnForbidden()
6177
{
@@ -119,6 +135,21 @@ public async Task GetAsyncDomain_GetCustomers_ShouldReturnOK()
119135
responseContent.Should().NotBeNullOrEmpty();
120136
}
121137

138+
[Fact(DisplayName = "Should return Ok and get customers from unauthorized url")]
139+
public async Task GetAsyncUnauthorized_GetCustomers_ShouldReturnOK()
140+
{
141+
// Arrange
142+
_url += $"/unauthorized?returnCustomer={true}";
143+
144+
// Act
145+
var response = await _client.GetAsync(_url);
146+
147+
// Assert
148+
response.Should().Be200Ok();
149+
var responseContent = await response.Content.ReadAsAsync<IEnumerable<Customer>>();
150+
responseContent.Should().NotBeNullOrEmpty();
151+
}
152+
122153
[Fact(DisplayName = "Should return Ok and get customers from cannot access url")]
123154
public async Task GetAsyncCannotAccess_GetCustomers_ShouldReturnOK()
124155
{

tests/CustomExceptionsTests.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,58 @@ public class CustomExceptionsTests
1212
private readonly string _errorMessage = "Custom error message example";
1313
private readonly string _exceptionType = "NEWEXCEPTION_ERROR";
1414

15+
#region UnauthorizedException
16+
[Fact(DisplayName = "Should throw unauthorized exception")]
17+
public void NewUnauthorizedException_ThrowException_ShouldThrowUnauthorizedException()
18+
{
19+
// Act
20+
Action action = () => throw new UnauthorizedException();
21+
22+
// Assert
23+
action.Should().Throw<UnauthorizedException>();
24+
}
25+
26+
[Fact(DisplayName = "Should throw unauthorized exception with message")]
27+
public void NewUnauthorizedException_ThrowException_ShouldThrowUnauthorizedExceptionWithMessage()
28+
{
29+
// Act
30+
Action action = () => throw new UnauthorizedException(_errorMessage);
31+
32+
// Assert
33+
action.Should().Throw<UnauthorizedException>().WithMessage(_errorMessage);
34+
}
35+
36+
[Fact(DisplayName = "Should throw unauthorized exception with message and inner exception")]
37+
public void NewUnauthorizedException_ThrowException_ShouldThrowUnauthorizedExceptionWithMessageAndInnerException()
38+
{
39+
// Act
40+
Action action = () => throw new UnauthorizedException(_errorMessage, new UnauthorizedException());
41+
42+
// Assert
43+
action.Should().Throw<UnauthorizedException>().WithMessage(_errorMessage).WithInnerException<UnauthorizedException>();
44+
}
45+
46+
[Fact(DisplayName = "Should throw unauthorized exception with message and exception type")]
47+
public void NewUnauthorizedException_ThrowException_ShouldThrowUnauthorizedExceptionWithMessageAndExceptionType()
48+
{
49+
// Act
50+
Action action = () => throw new UnauthorizedException(_errorMessage, _exceptionType);
51+
52+
// Assert
53+
action.Should().Throw<UnauthorizedException>().WithMessage(_errorMessage);
54+
}
55+
56+
[Fact(DisplayName = "Should throw unauthorized exception with message, exception type and inner exception")]
57+
public void NewUnauthorizedException_ThrowException_ShouldThrowUnauthorizedExceptionWithMessageAndExceptionTypeAndInnerException()
58+
{
59+
// Act
60+
Action action = () => throw new UnauthorizedException(_errorMessage, _exceptionType, new UnauthorizedException());
61+
62+
// Assert
63+
action.Should().Throw<UnauthorizedException>().WithMessage(_errorMessage).WithInnerException<UnauthorizedException>();
64+
}
65+
#endregion
66+
1567
#region CannotAccessException
1668
[Fact(DisplayName = "Should throw cannot access exception")]
1769
public void NewCannotAccessException_ThrowException_ShouldThrowCannotAccessException()

0 commit comments

Comments
 (0)