Merge pull request #2638 from JaySoni1/WEB-307-when-accessing-a-client-without-a-profile-picture-an-error-is-passed-on-to-the-ui

WEB-307: Fix error when accessing client without profile picture
This commit is contained in:
Gopi Kishan
2025-09-09 13:01:45 +05:30
committed by GitHub
3 changed files with 46 additions and 14 deletions
@@ -92,17 +92,17 @@ export class ClientsViewComponent implements OnInit {
ngOnInit() { ngOnInit() {
this.clientsService.getClientProfileImage(this.clientViewData.id).subscribe({ this.clientsService.getClientProfileImage(this.clientViewData.id).subscribe({
next: (base64Image: any) => { next: (base64Image: any) => {
this.clientImage = this._sanitizer.bypassSecurityTrustResourceUrl(base64Image); // If base64Image is null, client has no profile image
}, if (base64Image) {
error: (error: any) => { this.clientImage = this._sanitizer.bypassSecurityTrustResourceUrl(base64Image);
// 404 is expected when client has no profile image - not an error
if (error.status === 404) {
this.clientImage = null;
} else { } else {
// Log other unexpected errors
console.error('Error loading client profile image:', error);
this.clientImage = null; this.clientImage = null;
} }
},
error: (error: any) => {
// Handle any unexpected errors
console.error('Error loading client profile image:', error);
this.clientImage = null;
} }
}); });
} }
+19 -2
View File
@@ -3,7 +3,8 @@ import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http'; import { HttpClient, HttpParams } from '@angular/common/http';
/** rxjs Imports */ /** rxjs Imports */
import { Observable } from 'rxjs'; import { Observable, of, throwError } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
/** /**
* Clients service. * Clients service.
@@ -171,7 +172,23 @@ export class ClientsService {
getClientProfileImage(clientId: string) { getClientProfileImage(clientId: string) {
const httpParams = new HttpParams().set('maxHeight', '150'); const httpParams = new HttpParams().set('maxHeight', '150');
return this.http.get(`/clients/${clientId}/images`, { params: httpParams, responseType: 'text' }); // Keep it simple since our interceptor will handle the 404 errors
return this.http
.get(`/clients/${clientId}/images`, {
params: httpParams,
responseType: 'text'
})
.pipe(
// Handle the error here and return null when no image is found (404)
catchError((error) => {
if (error.status === 404) {
// Client has no profile image - return null without propagating error
return of(null);
}
// For other errors, rethrow the error
return throwError(() => error);
})
);
} }
uploadClientProfileImage(clientId: string, image: File) { uploadClientProfileImage(clientId: string, image: File) {
+19 -4
View File
@@ -12,6 +12,7 @@ import { environment } from '../../../environments/environment';
/** Custom Services */ /** Custom Services */
import { Logger } from '../logger/logger.service'; import { Logger } from '../logger/logger.service';
import { AlertService } from '../alert/alert.service'; import { AlertService } from '../alert/alert.service';
import { TranslateService } from '@ngx-translate/core'; // Added import for TranslateService
/** Initialize Logger */ /** Initialize Logger */
const log = new Logger('ErrorHandlerInterceptor'); const log = new Logger('ErrorHandlerInterceptor');
@@ -23,20 +24,24 @@ const log = new Logger('ErrorHandlerInterceptor');
export class ErrorHandlerInterceptor implements HttpInterceptor { export class ErrorHandlerInterceptor implements HttpInterceptor {
/** /**
* @param {AlertService} alertService Alert Service. * @param {AlertService} alertService Alert Service.
* @param {TranslateService} translate Translation Service.
*/ */
constructor(private alertService: AlertService) {} constructor(
private alertService: AlertService,
private translate: TranslateService // Added TranslateService
) {}
/** /**
* Intercepts a Http request and adds a default error handler. * Intercepts a Http request and adds a default error handler.
*/ */
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(catchError((error) => this.handleError(error))); return next.handle(request).pipe(catchError((error) => this.handleError(error, request)));
} }
/** /**
* Error handler. * Error handler.
*/ */
private handleError(response: HttpErrorResponse): Observable<HttpEvent<any>> { private handleError(response: HttpErrorResponse, request: HttpRequest<any>): Observable<HttpEvent<any>> {
const status = response.status; const status = response.status;
let errorMessage = response.error.developerMessage || response.message; let errorMessage = response.error.developerMessage || response.message;
if (response.error.errors) { if (response.error.errors) {
@@ -64,7 +69,17 @@ export class ErrorHandlerInterceptor implements HttpInterceptor {
message: errorMessage || 'You are not authorized for this request!' message: errorMessage || 'You are not authorized for this request!'
}); });
} else if (status === 404) { } else if (status === 404) {
this.alertService.alert({ type: 'Resource does not exist', message: errorMessage || 'Resource does not exist!' }); // Check if this is an image request that should be silently handled (client profile image)
if (request.url.includes('/clients/') && request.url.includes('/images')) {
// Don't show alerts for missing client images
// This is an expected condition, not an error
return new Observable<HttpEvent<any>>();
} else {
this.alertService.alert({
type: this.translate.instant('error.resource.not.found'),
message: errorMessage || 'Resource does not exist!'
});
}
} else if (status === 500) { } else if (status === 500) {
this.alertService.alert({ this.alertService.alert({
type: 'Internal Server Error', type: 'Internal Server Error',