Skip to content

Commit

Permalink
- Add http error interceptor
Browse files Browse the repository at this point in the history
- Add error modal

Signed-off-by: damianw345 <damianw345@gmail.com>
  • Loading branch information
damianw345 committed Jul 18, 2020
1 parent 360f4a0 commit 5846bcc
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 14 deletions.
20 changes: 18 additions & 2 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ import { MaterialModule } from './material.module';
import { ReactiveFormsModule } from '@angular/forms';
import { JwtInterceptor } from './core/http/jwt-interceptor';
import { OAuthCallbackComponent } from './components/oauth-callback/o-auth-callback.component';
import { ErrorDialogComponent } from './components/message-dialog/error-dialog.component';
import { ErrorInterceptor } from './core/http/error-interceptor';
import { MatIconModule } from '@angular/material/icon';
import { MatDialogModule } from '@angular/material/dialog';


@NgModule({
Expand All @@ -31,22 +35,34 @@ import { OAuthCallbackComponent } from './components/oauth-callback/o-auth-callb
BreadcrumbComponent,
LoginComponent,
OAuthCallbackComponent,
ErrorDialogComponent,
],
imports: [
BrowserModule,
HttpClientModule,
AppRoutingModule,
BrowserAnimationsModule,
ReactiveFormsModule,
MaterialModule
MaterialModule,
MatIconModule,
MatDialogModule,
],
entryComponents: [
ErrorDialogComponent
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: JwtInterceptor,
multi: true
},
{
provide: HTTP_INTERCEPTORS,
useClass: ErrorInterceptor,
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
export class AppModule {
}
1 change: 1 addition & 0 deletions src/app/components/login/login.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
matInput
placeholder="Password"
type="password">
<mat-hint>Min 8 chars</mat-hint>
</mat-form-field>
</div>
</article>
Expand Down
15 changes: 4 additions & 11 deletions src/app/components/login/login.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import { UserService } from '../../core/service/user.service';
import { LoginData } from '../../core/model/login-data';
import { Router } from '@angular/router';
import { RegistrationService } from '../../core/http/registration.service';
import { catchError, tap } from 'rxjs/operators';
import { throwError } from 'rxjs';
import { tap } from 'rxjs/operators';
import { OAuthRedirectionUrlService } from '../../core/http/o-auth-redirection-url.service';

@Component({
Expand All @@ -26,8 +25,8 @@ export class LoginComponent implements OnInit {

ngOnInit(): void {
this.loginForm = this.formBuilder.group({
email: ['', Validators.required],
password: ['', Validators.required]
email: ['', [Validators.required, Validators.pattern(/^\S+@\S+\.\S+$/)]],
password: ['', [Validators.required, Validators.minLength(8)]]
});
}

Expand All @@ -49,14 +48,8 @@ export class LoginComponent implements OnInit {
.pipe(
tap(registration => {
this.loginWithPassword();
}),
// TODO add error interceptor
catchError(err => {
console.error(err);
return throwError(err);
})
)
.subscribe();
).subscribe();
}
}

Expand Down
16 changes: 16 additions & 0 deletions src/app/components/message-dialog/error-dialog.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<div>
<div class="row pb-4 justify-content-center">
<div class="col-12">
<p *ngIf="errorMessage?.message !== ''" class="text-center">Error message: {{ errorMessage?.message }}</p>
<p *ngIf="errorMessage?.details?.length > 0" class="text-center">Error details: {{ errorMessage?.details}}</p>
<p *ngIf="errorMessage?.refNumber !== ''" class="text-center">Error ref: {{ errorMessage?.refNumber }}</p>
<p *ngIf="errorMessage?.dateTime" class="text-center">Error time: {{ errorMessage?.dateTime }}</p>
</div>
</div>

<div class="row justify-content-center">
<div class="mb-0 pb-0 ">
<button color="primary" mat-button mat-dialog-close mat-raised-button>CLOSE</button>
</div>
</div>
</div>
Empty file.
17 changes: 17 additions & 0 deletions src/app/components/message-dialog/error-dialog.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Component, Inject } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { ErrorMessage } from '../../core/model/error-message.model';

@Component({
selector: 'app-message-dialog',
templateUrl: './error-dialog.component.html',
styleUrls: ['./error-dialog.component.scss']
})
export class ErrorDialogComponent {

errorMessage: ErrorMessage;

constructor(@Inject(MAT_DIALOG_DATA) data: { errorMessage: ErrorMessage }) {
this.errorMessage = data.errorMessage;
}
}
34 changes: 34 additions & 0 deletions src/app/core/http/error-interceptor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import { ModalFacadeService } from '../service/modal.service';
import { UserService } from '../service/user.service';
import { ErrorMessage } from '../model/error-message.model';

@Injectable()
export class ErrorInterceptor implements HttpInterceptor {

constructor(private userService: UserService,
private modalFacadeService: ModalFacadeService) {
}

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(
catchError(err => {
this.handleError(err);
return throwError('error');
})
);
}

private handleError(httpErrorResponse: HttpErrorResponse): void {
this.showErrorDialog(httpErrorResponse.error);
}

private showErrorDialog(message: ErrorMessage): void {
this.modalFacadeService.openErrorDialog(message)
.afterClosed()
.subscribe(_ => this.userService.logout());
}
}
10 changes: 10 additions & 0 deletions src/app/core/model/error-message.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export class ErrorMessage {
constructor(
public code: string,
public message: string,
public dateTime: Date,
public refNumber: string,
public details?: string[],
) {
}
}
21 changes: 21 additions & 0 deletions src/app/core/service/modal.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Injectable } from '@angular/core';
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { ErrorDialogComponent } from '../../components/message-dialog/error-dialog.component';
import { ErrorMessage } from '../model/error-message.model';

@Injectable({
providedIn: 'root'
})
export class ModalFacadeService {

constructor(private dialog: MatDialog) {
}

openErrorDialog(errorMessage: ErrorMessage): MatDialogRef<ErrorDialogComponent> {
return this.dialog.open(ErrorDialogComponent, {
data: {
errorMessage
}
});
}
}
2 changes: 1 addition & 1 deletion src/app/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default class Utils {
try {
return jwtDecode(token);
} catch (err) {
console.log('Error during parsing token: ', err);
console.error('Error during parsing token: ', err);
return null;
}
}
Expand Down

0 comments on commit 5846bcc

Please sign in to comment.