Skip to content

Commit 08f009e

Browse files
author
Ahmad El Lahib
committed
Refactor exception handling
1 parent 46130c2 commit 08f009e

38 files changed

+497
-1373
lines changed

src/CourseLibrary/CourseLibrary.API/Brokers/Caches/CacheBroker.Categories.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ public partial class CacheBroker
77
{
88
private const string CategoriesCacheKey = "CategoriesCacheKey";
99

10-
public List<Category> GetCachedCategories()
10+
public List<Category>? GetCachedCategories()
1111
{
12-
return GetCache<List<Category>>(CategoriesCacheKey);
12+
return GetCache<List<Category>?>(CategoriesCacheKey);
1313
}
1414

1515
public void SetCachedCategories(List<Category> categoriesList)

src/CourseLibrary/CourseLibrary.API/Brokers/Caches/ICacheBroker.Categories.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace CourseLibrary.API.Brokers.Caches;
44

55
public partial interface ICacheBroker
66
{
7-
List<Category> GetCachedCategories();
7+
List<Category>? GetCachedCategories();
88
void SetCachedCategories(List<Category> categoriesList);
99
void ClearCachedCategories();
1010
}

src/CourseLibrary/CourseLibrary.API/Brokers/Loggings/ILoggingBroker.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ public interface ILoggingBroker<T> where T : class
1010

1111
void LogInformation(string message, params object?[] args);
1212

13-
void LogWarning(string message);
13+
void LogWarning(string message, params object?[] args);
1414

15-
void LogError(Exception exception);
15+
void LogError(Exception exception, string instance);
1616

17-
void LogCritical(Exception exception);
17+
void LogCritical(string instance, Exception exception);
1818
}

src/CourseLibrary/CourseLibrary.API/Brokers/Loggings/LoggingBroker.cs

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ public void LogTrace(string message) =>
2121
public void LogInformation(string message, params object?[] args) =>
2222
_logger.LogInformation(message, args);
2323

24-
public void LogWarning(string message) =>
25-
_logger.LogWarning(message);
24+
public void LogWarning(string message, params object?[] args) =>
25+
_logger.LogWarning(message, args);
2626

27-
public void LogError(Exception exception)
27+
public void LogError(Exception exception, string instance)
2828
{
29-
StringBuilder sb = new($"{exception.Message}{Environment.NewLine}");
29+
StringBuilder sb = new($"{instance} {exception.Message}{Environment.NewLine}");
3030

3131
if (exception.InnerException != null)
3232
{
@@ -36,29 +36,14 @@ public void LogError(Exception exception)
3636
{
3737
sb.AppendLine(exception.InnerException.InnerException.Message);
3838
}
39-
40-
foreach (object? key in exception.InnerException.Data.Keys)
41-
{
42-
string keyMessage = $" {key}: ";
43-
sb.AppendLine(keyMessage);
44-
45-
List<string>? list = exception.InnerException.Data[key] as List<string>;
46-
if (list is not null)
47-
48-
for (int i = 0; i < list.Count; i++)
49-
{
50-
string? value = list[i];
51-
sb.AppendLine($" {value}");
52-
}
53-
}
5439
}
5540

5641
_logger.LogError(sb.ToString(), exception);
5742
}
5843

59-
public void LogCritical(Exception exception)
44+
public void LogCritical(string instance, Exception exception)
6045
{
61-
StringBuilder sb = new($"{exception.Message}");
46+
StringBuilder sb = new($"{instance} {exception.Message}{Environment.NewLine}");
6247

6348
if (exception.InnerException != null)
6449
{
@@ -70,6 +55,8 @@ public void LogCritical(Exception exception)
7055
}
7156
}
7257

58+
sb.Append($"{Environment.NewLine}StackTrace: {exception.StackTrace}");
59+
7360
_logger.LogCritical(exception, sb.ToString());
7461
}
7562
}
Lines changed: 28 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using CourseLibrary.API.Contracts.Authors;
22
using CourseLibrary.API.Filters;
33
using CourseLibrary.API.Models.Authors;
4-
using CourseLibrary.API.Models.Exceptions;
54
using CourseLibrary.API.Pagination;
65
using CourseLibrary.API.Services.V1.Authors;
76
using Microsoft.AspNetCore.Mvc;
@@ -31,16 +30,9 @@ public AuthorsController(IAuthorOrchestrationService authorOrchestrationService)
3130
[ProducesResponseType(typeof(string), StatusCodes.Status500InternalServerError)]
3231
public async ValueTask<IActionResult> GetAuthorAsync([FromRoute] Guid authorId, [FromServices] IOptions<ApiBehaviorOptions> apiBehaviorOptions, CancellationToken cancellationToken)
3332
{
34-
try
35-
{
36-
Author author = await _authorOrchestrationService.RetrieveAuthorByIdAsync(authorId, cancellationToken);
33+
Author author = await _authorOrchestrationService.RetrieveAuthorByIdAsync(authorId, cancellationToken);
3734

38-
return Ok((AuthorDto)author);
39-
}
40-
catch (Exception exception)
41-
{
42-
return HandleException(exception, apiBehaviorOptions, ControllerContext);
43-
}
35+
return Ok((AuthorDto)author);
4436
}
4537

4638
[HttpPost]
@@ -52,16 +44,9 @@ public async ValueTask<IActionResult> GetAuthorAsync([FromRoute] Guid authorId,
5244
[ProducesResponseType(typeof(string), StatusCodes.Status500InternalServerError)]
5345
public async Task<IActionResult> PostAuthorAsync([FromBody] AuthorForCreation authorForCreation, [FromServices] IOptions<ApiBehaviorOptions> apiBehaviorOptions, CancellationToken cancellationToken)
5446
{
55-
try
56-
{
57-
Author addedAuthor = await _authorOrchestrationService.CreateAuthorAsync((Author)authorForCreation, cancellationToken);
47+
Author addedAuthor = await _authorOrchestrationService.CreateAuthorAsync((Author)authorForCreation, cancellationToken);
5848

59-
return CreatedAtRoute(nameof(GetAuthorAsync), new { authorId = addedAuthor.Id }, (AuthorCreatedDto)addedAuthor);
60-
}
61-
catch (Exception exception)
62-
{
63-
return HandleException(exception, apiBehaviorOptions, ControllerContext);
64-
}
49+
return CreatedAtRoute(nameof(GetAuthorAsync), new { authorId = addedAuthor.Id }, (AuthorCreatedDto)addedAuthor);
6550
}
6651

6752
[HttpPatch("{authorId}")]
@@ -73,18 +58,11 @@ public async Task<IActionResult> PostAuthorAsync([FromBody] AuthorForCreation au
7358
[ProducesResponseType(typeof(string), StatusCodes.Status500InternalServerError)]
7459
public async Task<IActionResult> PatchAuthorAsync([FromRoute] Guid authorId, [FromBody] AuthorForUpdate authorForUpdate, [FromServices] IOptions<ApiBehaviorOptions> apiBehaviorOptions, CancellationToken cancellationToken)
7560
{
76-
try
77-
{
78-
Author author = (Author)authorForUpdate;
79-
author.Id = authorId;
80-
Author storageAuthor = await _authorOrchestrationService.ModifyAuthorAsync(author, cancellationToken);
61+
Author author = (Author)authorForUpdate;
62+
author.Id = authorId;
63+
Author storageAuthor = await _authorOrchestrationService.ModifyAuthorAsync(author, cancellationToken);
8164

82-
return Ok((AuthorUpdatedDto)storageAuthor);
83-
}
84-
catch (Exception exception)
85-
{
86-
return HandleException(exception, apiBehaviorOptions, ControllerContext);
87-
}
65+
return Ok((AuthorUpdatedDto)storageAuthor);
8866
}
8967

9068
[HttpDelete("{authorId}")]
@@ -95,16 +73,9 @@ public async Task<IActionResult> PatchAuthorAsync([FromRoute] Guid authorId, [Fr
9573
[ProducesResponseType(typeof(string), StatusCodes.Status500InternalServerError)]
9674
public async Task<IActionResult> DeleteAuthorAsync(Guid authorId, [FromServices] IOptions<ApiBehaviorOptions> apiBehaviorOptions, CancellationToken cancellationToken)
9775
{
98-
try
99-
{
100-
await _authorOrchestrationService.RemoveAuthorByIdAsync(authorId, cancellationToken);
76+
await _authorOrchestrationService.RemoveAuthorByIdAsync(authorId, cancellationToken);
10177

102-
return NoContent();
103-
}
104-
catch (Exception exception)
105-
{
106-
return HandleException(exception, apiBehaviorOptions, ControllerContext);
107-
}
78+
return NoContent();
10879
}
10980

11081
[HttpGet(Name = nameof(SearchAuthorsAsync))]
@@ -113,37 +84,25 @@ public async Task<IActionResult> DeleteAuthorAsync(Guid authorId, [FromServices]
11384
[ProducesResponseType(typeof(string), StatusCodes.Status500InternalServerError)]
11485
public ActionResult<IEnumerable<AuthorDto>> SearchAuthorsAsync([FromQuery] AuthorResourceParameters authorResourceParameters)
11586
{
116-
try
117-
{
118-
PagedList<Author> storagePagedAuthors = _authorOrchestrationService.SearchAuthors(authorResourceParameters);
119-
120-
PaginationMetaData PaginationMetaData = new()
121-
{
122-
TotalCount = storagePagedAuthors.TotalCount,
123-
PageSize = storagePagedAuthors.PageSize,
124-
CurrentPage = storagePagedAuthors.CurrentPage,
125-
TotalPages = storagePagedAuthors.TotalPages,
126-
HasPrevious = storagePagedAuthors.HasPrevious,
127-
HasNext = storagePagedAuthors.HasNext,
128-
PreviousPageLink = storagePagedAuthors.HasPrevious ? CreateAuthorResourceUri(authorResourceParameters, ResourceUriType.PreviousPage) : string.Empty,
129-
NextPageLink = storagePagedAuthors.HasNext ? CreateAuthorResourceUri(authorResourceParameters, ResourceUriType.NextPage) : string.Empty
130-
};
131-
132-
Response.Headers.Add("X-Pagination", JsonSerializer.Serialize(PaginationMetaData));
133-
134-
List<AuthorDto> authorsDtos = new();
135-
136-
foreach (Author author in storagePagedAuthors)
137-
{
138-
authorsDtos.Add((AuthorDto)author);
139-
}
140-
141-
return Ok(authorsDtos);
142-
}
143-
catch (Exception exception)
87+
PagedList<Author> storagePagedAuthors = _authorOrchestrationService.SearchAuthors(authorResourceParameters);
88+
89+
PaginationMetaData paginationMetaData = new()
14490
{
145-
return (ActionResult)HandleException(exception);
146-
}
91+
TotalCount = storagePagedAuthors.TotalCount,
92+
PageSize = storagePagedAuthors.PageSize,
93+
CurrentPage = storagePagedAuthors.CurrentPage,
94+
TotalPages = storagePagedAuthors.TotalPages,
95+
HasPrevious = storagePagedAuthors.HasPrevious,
96+
HasNext = storagePagedAuthors.HasNext,
97+
PreviousPageLink = storagePagedAuthors.HasPrevious ? CreateAuthorResourceUri(authorResourceParameters, ResourceUriType.PreviousPage) : string.Empty,
98+
NextPageLink = storagePagedAuthors.HasNext ? CreateAuthorResourceUri(authorResourceParameters, ResourceUriType.NextPage) : string.Empty
99+
};
100+
101+
Response.Headers.Append("X-Pagination", JsonSerializer.Serialize(paginationMetaData));
102+
103+
List<AuthorDto> authorsDto = storagePagedAuthors.Select(author => (AuthorDto)author).ToList();
104+
105+
return Ok(authorsDto);
147106
}
148107

149108
private string CreateAuthorResourceUri(AuthorResourceParameters authorResourceParameters, ResourceUriType type)
@@ -188,33 +147,4 @@ private string CreateAuthorResourceUri(AuthorResourceParameters authorResourcePa
188147

189148
return resourceUri is null ? string.Empty : resourceUri.Replace("http://", "https://");
190149
}
191-
192-
private IActionResult HandleException(Exception exception, IOptions<ApiBehaviorOptions>? apiBehaviorOptions = null, ActionContext? actionContext = null)
193-
{
194-
switch (exception)
195-
{
196-
case ResourceParametersException:
197-
return BadRequest(exception.Message);
198-
case CancellationException:
199-
return NoContent();
200-
case ValidationException when exception.InnerException is NotFoundEntityException<Author>:
201-
return NotFound(GetInnerMessage(exception));
202-
case ValidationException:
203-
if (apiBehaviorOptions is null || actionContext is null)
204-
throw new ArgumentNullException(nameof(apiBehaviorOptions));
205-
206-
SetModelState(ModelState, (ValidationException)exception);
207-
208-
return apiBehaviorOptions!.Value.InvalidModelStateResponseFactory(actionContext!);
209-
case IDependencyException when (exception.InnerException is DbConflictException):
210-
return Conflict(exception.Message);
211-
case IDependencyException when (exception.InnerException is LockedEntityException<Author>):
212-
return Problem(GetInnerMessage(exception));
213-
case IServiceException:
214-
return Problem(StaticData.ControllerMessages.InternalServerError);
215-
default:
216-
LoggingBroker.LogError(exception);
217-
return Problem(StaticData.ControllerMessages.InternalServerError);
218-
}
219-
}
220150
}

0 commit comments

Comments
 (0)