-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Jovan Arsov
committed
Apr 11, 2022
1 parent
f25322c
commit 06b6439
Showing
22 changed files
with
339 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using API.Data; | ||
using API.Entities; | ||
using Microsoft.AspNetCore.Authorization; | ||
using Microsoft.AspNetCore.Mvc; | ||
|
||
namespace API.Controllers | ||
{ | ||
public class BuggyController : BaseApiController | ||
{ | ||
private readonly DataContext _context; | ||
public BuggyController(DataContext context) | ||
{ | ||
_context = context; | ||
} | ||
|
||
[Authorize] | ||
[HttpGet("auth")] | ||
public ActionResult<string> GetSecret() | ||
{ | ||
return "secret text"; | ||
} | ||
|
||
[HttpGet("not-found")] | ||
public ActionResult<AppUser> GetNotFound() | ||
{ | ||
var thing = _context.Users.Find(-1); | ||
|
||
if(thing == null) return NotFound(); | ||
|
||
return Ok(); | ||
} | ||
|
||
[HttpGet("server-error")] | ||
public ActionResult<string> GetServerError() | ||
{ | ||
var thing = _context.Users.Find(-1); | ||
|
||
var thingToReturn = thing.ToString(); | ||
|
||
return thingToReturn; | ||
} | ||
|
||
[HttpGet("bad-request")] | ||
public ActionResult<string> GetBadRequest(){ | ||
return BadRequest("This was not a good request"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
|
||
namespace API.Errors | ||
{ | ||
public class ApiException | ||
{ | ||
public ApiException(int statusCode, string message = null, string details = null) | ||
{ | ||
StatusCode = statusCode; | ||
Message = message; | ||
Details = details; | ||
} | ||
|
||
public int StatusCode { get; set; } | ||
public string Message { get; set; } | ||
public string Details { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Net; | ||
using System.Text.Json; | ||
using System.Threading.Tasks; | ||
using API.Errors; | ||
|
||
namespace API.Middleware | ||
{ | ||
public class ExceptionMiddleware | ||
{ | ||
private readonly RequestDelegate _next; | ||
private readonly ILogger<ExceptionMiddleware> _logger; | ||
private readonly IHostEnvironment _env; | ||
|
||
public ExceptionMiddleware(RequestDelegate next, ILogger<ExceptionMiddleware> logger, | ||
IHostEnvironment env) | ||
{ | ||
_env = env; | ||
_logger = logger; | ||
_next = next; | ||
} | ||
|
||
public async Task InvokeAsync(HttpContext context) | ||
{ | ||
try | ||
{ | ||
await _next(context); | ||
} | ||
catch(Exception ex) | ||
{ | ||
_logger.LogError(ex, ex.Message); | ||
context.Response.ContentType = "application/json"; | ||
context.Response.StatusCode = (int) HttpStatusCode.InternalServerError; | ||
|
||
var response = _env.IsDevelopment() | ||
? new ApiException(context.Response.StatusCode, ex.Message, ex.StackTrace?.ToString()) | ||
: new ApiException(context.Response.StatusCode, "Internal server error"); | ||
|
||
var options = new JsonSerializerOptions{PropertyNamingPolicy = JsonNamingPolicy.CamelCase}; | ||
|
||
var json = JsonSerializer.Serialize(response, options); | ||
|
||
await context.Response.WriteAsync(json); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { Injectable } from '@angular/core'; | ||
import { | ||
HttpRequest, | ||
HttpHandler, | ||
HttpEvent, | ||
HttpInterceptor | ||
} from '@angular/common/http'; | ||
import { Observable, throwError } from 'rxjs'; | ||
import { NavigationExtras, Router } from '@angular/router'; | ||
import { ToastrService } from 'ngx-toastr'; | ||
import { catchError } from 'rxjs/operators'; | ||
|
||
@Injectable() | ||
export class ErrorInterceptor implements HttpInterceptor { | ||
|
||
constructor(private router: Router, private toastr: ToastrService) {} | ||
|
||
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { | ||
return next.handle(request).pipe( | ||
catchError(error =>{ | ||
if(error){ | ||
switch (error.status) { | ||
case 400: | ||
if(error.error.errors){ | ||
const modalStateErrors = []; | ||
for(const key in error.error.errors){ | ||
if(error.error.errors[key]){ | ||
modalStateErrors.push(error.error.errors[key]) | ||
} | ||
} | ||
throw modalStateErrors.flat(); | ||
}else{ | ||
this.toastr.error(error.statusText === "OK" ? "Bad Request" : error.statusText, error.status); | ||
} | ||
break; | ||
case 401: | ||
//this.toastr.error(error.error === null ? "Unauthorized" : error.error, error.status) | ||
this.toastr.error(error.statusText === "OK" ? "Unauthorised" : error.statusText, error.status); | ||
break; | ||
case 404: | ||
this.router.navigateByUrl('/not-found'); | ||
break; | ||
case 500: | ||
const navigationExtras: NavigationExtras = {state: {error: error.error}}; | ||
this.router.navigateByUrl('/server-error', navigationExtras); | ||
break; | ||
default: | ||
this.toastr.error('Something unexpected went wrong'); | ||
console.log(error); | ||
break; | ||
} | ||
} | ||
return throwError(error); | ||
}) | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<div class="container"> | ||
<h1>Not found</h1> | ||
<button class="btn btn-info btn-lg" routerLink="/">Return to home page</button> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { Component, OnInit } from '@angular/core'; | ||
|
||
@Component({ | ||
selector: 'app-not-found', | ||
templateUrl: './not-found.component.html', | ||
styleUrls: ['./not-found.component.css'] | ||
}) | ||
export class NotFoundComponent implements OnInit { | ||
|
||
constructor() { } | ||
|
||
ngOnInit(): void { | ||
} | ||
|
||
} |
Empty file.
15 changes: 15 additions & 0 deletions
15
client/src/app/errors/server-error/server-error.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<h4>Internal server error - refreshing the page will make the error disappear!</h4> | ||
<ng-container *ngIf="error"> | ||
<h5 class="text-danger">Error: {{error.message}}</h5> | ||
<p class="font-weight-bold">Note: If you are seeing this, then Angular is probably not to blame</p> | ||
<p>What to do next?</p> | ||
<ol> | ||
<li>Open the chrome dev tools</li> | ||
<li>Inspect the network tab </li> | ||
<li>Check the failing request</li> | ||
<li>Examing the request URL - make sure it is correct</li> | ||
<li>Reproduse the error in Postman - if we see the same response then the issue is not with Angular</li> | ||
</ol> | ||
<p>Following is the stack trace - this is where your investigation should start!</p> | ||
<code class="mt-5" style="background-color: whitesmoke;">{{error.details}}</code> | ||
</ng-container> |
20 changes: 20 additions & 0 deletions
20
client/src/app/errors/server-error/server-error.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { Component, OnInit } from '@angular/core'; | ||
import { Router } from '@angular/router'; | ||
|
||
@Component({ | ||
selector: 'app-server-error', | ||
templateUrl: './server-error.component.html', | ||
styleUrls: ['./server-error.component.css'] | ||
}) | ||
export class ServerErrorComponent implements OnInit { | ||
error: any; | ||
|
||
constructor(private router: Router) { | ||
const navigation = this.router.getCurrentNavigation(); | ||
this.error = navigation?.extras?.state?.error; | ||
} | ||
|
||
ngOnInit(): void { | ||
} | ||
|
||
} |
Empty file.
15 changes: 15 additions & 0 deletions
15
client/src/app/errors/test-errors/test-errors.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<ng-container> | ||
<button (click)="get500Error()" class="btn btn-outline-primary mr-3">Test 500 Error</button> | ||
<button (click)="get400Error()" class="btn btn-outline-primary mr-3">Test 400 Error</button> | ||
<button (click)="get401Error()" class="btn btn-outline-primary mr-3">Test 401 Error</button> | ||
<button (click)="get404Error()" class="btn btn-outline-primary mr-3">Test 404 Error</button> | ||
<button (click)="get400ValidationError()" class="btn btn-outline-primary mr-3"> | ||
Test 400 Validation Error</button> | ||
<div class="row mt-5" *ngIf="validationErrors.length > 0"> | ||
<ul class="text-danger"> | ||
<li *ngFor="let error of validationErrors"> | ||
{{error}} | ||
</li> | ||
</ul> | ||
</div> | ||
</ng-container> |
Oops, something went wrong.
06b6439
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error.statusText always returns status OK(), check the switch component in Error.ErrorInterceptor.ts and also see this solution angular/angular#23334