[NIFI-13104] Unknown Route handling (#8725)

* [NIFI-13104] - Unknown route handling

* Add method to the ErrorHelper that safely gets an error string from an HttpErrorResponse object

* review feedback

* use errorHelper.fullScreenError in favor of directly calling the fullScreenError action

This closes #8725
This commit is contained in:
Rob Fellows 2024-05-02 14:26:24 -04:00 committed by GitHub
parent 49c8d1b490
commit f87a0f47ef
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
50 changed files with 545 additions and 202 deletions

View File

@ -18,6 +18,7 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { authenticationGuard } from './service/guard/authentication.guard'; import { authenticationGuard } from './service/guard/authentication.guard';
import { RouteNotFound } from './pages/route-not-found/feature/route-not-found.component';
const routes: Routes = [ const routes: Routes = [
{ {
@ -101,6 +102,12 @@ const routes: Routes = [
canMatch: [authenticationGuard], canMatch: [authenticationGuard],
loadChildren: () => loadChildren: () =>
import('./pages/flow-designer/feature/flow-designer.module').then((m) => m.FlowDesignerModule) import('./pages/flow-designer/feature/flow-designer.module').then((m) => m.FlowDesignerModule)
},
{
path: '**',
component: RouteNotFound,
loadChildren: () =>
import('./pages/route-not-found/feature/route-not-found.module').then((m) => m.RouteNotFoundModule)
} }
]; ];

View File

@ -37,6 +37,7 @@ import { OverridePolicyDialog } from '../../ui/common/override-policy-dialog/ove
import { MEDIUM_DIALOG, SMALL_DIALOG } from '../../../../index'; import { MEDIUM_DIALOG, SMALL_DIALOG } from '../../../../index';
import { HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse } from '@angular/common/http';
import { loadCurrentUser } from '../../../../state/current-user/current-user.actions'; import { loadCurrentUser } from '../../../../state/current-user/current-user.actions';
import { ErrorHelper } from '../../../../service/error-helper.service';
@Injectable() @Injectable()
export class AccessPolicyEffects { export class AccessPolicyEffects {
@ -45,7 +46,8 @@ export class AccessPolicyEffects {
private store: Store<NiFiState>, private store: Store<NiFiState>,
private router: Router, private router: Router,
private accessPoliciesService: AccessPolicyService, private accessPoliciesService: AccessPolicyService,
private dialog: MatDialog private dialog: MatDialog,
private errorHelper: ErrorHelper
) {} ) {}
setAccessPolicy$ = createEffect(() => setAccessPolicy$ = createEffect(() =>
@ -128,7 +130,7 @@ export class AccessPolicyEffects {
return of( return of(
AccessPolicyActions.accessPolicyApiBannerError({ AccessPolicyActions.accessPolicyApiBannerError({
response: { response: {
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
} }
}) })
); );
@ -163,7 +165,7 @@ export class AccessPolicyEffects {
of( of(
AccessPolicyActions.accessPolicyApiBannerError({ AccessPolicyActions.accessPolicyApiBannerError({
response: { response: {
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
} }
}) })
) )
@ -240,7 +242,7 @@ export class AccessPolicyEffects {
of( of(
AccessPolicyActions.accessPolicyApiBannerError({ AccessPolicyActions.accessPolicyApiBannerError({
response: { response: {
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
} }
}) })
) )
@ -347,7 +349,7 @@ export class AccessPolicyEffects {
of( of(
AccessPolicyActions.accessPolicyApiBannerError({ AccessPolicyActions.accessPolicyApiBannerError({
response: { response: {
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
} }
}) })
) )
@ -420,7 +422,7 @@ export class AccessPolicyEffects {
of( of(
AccessPolicyActions.accessPolicyApiBannerError({ AccessPolicyActions.accessPolicyApiBannerError({
response: { response: {
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
} }
}) })
) )
@ -477,7 +479,7 @@ export class AccessPolicyEffects {
of( of(
AccessPolicyActions.accessPolicyApiBannerError({ AccessPolicyActions.accessPolicyApiBannerError({
response: { response: {
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
} }
}) })
) )

View File

@ -22,12 +22,14 @@ import * as ErrorActions from '../../../../state/error/error.actions';
import { catchError, from, map, of, switchMap } from 'rxjs'; import { catchError, from, map, of, switchMap } from 'rxjs';
import { AccessPolicyService } from '../../service/access-policy.service'; import { AccessPolicyService } from '../../service/access-policy.service';
import { HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse } from '@angular/common/http';
import { ErrorHelper } from '../../../../service/error-helper.service';
@Injectable() @Injectable()
export class PolicyComponentEffects { export class PolicyComponentEffects {
constructor( constructor(
private actions$: Actions, private actions$: Actions,
private accessPoliciesService: AccessPolicyService private accessPoliciesService: AccessPolicyService,
private errorHelper: ErrorHelper
) {} ) {}
loadPolicyComponent$ = createEffect(() => loadPolicyComponent$ = createEffect(() =>
@ -63,7 +65,7 @@ export class PolicyComponentEffects {
} else { } else {
return of( return of(
ErrorActions.snackBarError({ ErrorActions.snackBarError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
); );
} }

View File

@ -22,12 +22,14 @@ import * as ErrorActions from '../../../../state/error/error.actions';
import { catchError, combineLatest, map, of, switchMap } from 'rxjs'; import { catchError, combineLatest, map, of, switchMap } from 'rxjs';
import { AccessPolicyService } from '../../service/access-policy.service'; import { AccessPolicyService } from '../../service/access-policy.service';
import { HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse } from '@angular/common/http';
import { ErrorHelper } from '../../../../service/error-helper.service';
@Injectable() @Injectable()
export class TenantsEffects { export class TenantsEffects {
constructor( constructor(
private actions$: Actions, private actions$: Actions,
private accessPoliciesService: AccessPolicyService private accessPoliciesService: AccessPolicyService,
private errorHelper: ErrorHelper
) {} ) {}
loadTenants$ = createEffect(() => loadTenants$ = createEffect(() =>
@ -46,7 +48,7 @@ export class TenantsEffects {
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
ErrorActions.snackBarError({ ErrorActions.snackBarError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
) )
) )

View File

@ -17,6 +17,7 @@
import { createAction, props } from '@ngrx/store'; import { createAction, props } from '@ngrx/store';
import { ClusterListingEntity, ClusterNode, ClusterNodeEntity, SelectClusterNodeRequest } from './index'; import { ClusterListingEntity, ClusterNode, ClusterNodeEntity, SelectClusterNodeRequest } from './index';
import { HttpErrorResponse } from '@angular/common/http';
const CLUSTER_LISTING_PREFIX = '[Cluster Listing]'; const CLUSTER_LISTING_PREFIX = '[Cluster Listing]';
@ -70,7 +71,7 @@ export const removeNodeSuccess = createAction(
export const clusterNodeSnackbarError = createAction( export const clusterNodeSnackbarError = createAction(
`${CLUSTER_LISTING_PREFIX} Cluster Node Snackbar Error`, `${CLUSTER_LISTING_PREFIX} Cluster Node Snackbar Error`,
props<{ error: string }>() props<{ errorResponse: HttpErrorResponse }>()
); );
export const selectClusterNode = createAction( export const selectClusterNode = createAction(

View File

@ -110,7 +110,7 @@ export class ClusterListingEffects {
return ClusterListingActions.updateNodeSuccess({ response: entity }); return ClusterListingActions.updateNodeSuccess({ response: entity });
}), }),
catchError((errorResponse: HttpErrorResponse) => { catchError((errorResponse: HttpErrorResponse) => {
return of(ClusterListingActions.clusterNodeSnackbarError({ error: errorResponse.error })); return of(ClusterListingActions.clusterNodeSnackbarError({ errorResponse }));
}) })
) )
) )
@ -149,7 +149,7 @@ export class ClusterListingEffects {
return ClusterListingActions.updateNodeSuccess({ response: entity }); return ClusterListingActions.updateNodeSuccess({ response: entity });
}), }),
catchError((errorResponse: HttpErrorResponse) => { catchError((errorResponse: HttpErrorResponse) => {
return of(ClusterListingActions.clusterNodeSnackbarError({ error: errorResponse.error })); return of(ClusterListingActions.clusterNodeSnackbarError({ errorResponse }));
}) })
) )
) )
@ -188,7 +188,7 @@ export class ClusterListingEffects {
return ClusterListingActions.updateNodeSuccess({ response: entity }); return ClusterListingActions.updateNodeSuccess({ response: entity });
}), }),
catchError((errorResponse: HttpErrorResponse) => { catchError((errorResponse: HttpErrorResponse) => {
return of(ClusterListingActions.clusterNodeSnackbarError({ error: errorResponse.error })); return of(ClusterListingActions.clusterNodeSnackbarError({ errorResponse }));
}) })
) )
) )
@ -227,7 +227,7 @@ export class ClusterListingEffects {
return ClusterListingActions.removeNodeSuccess({ response: request }); return ClusterListingActions.removeNodeSuccess({ response: request });
}), }),
catchError((errorResponse: HttpErrorResponse) => { catchError((errorResponse: HttpErrorResponse) => {
return of(ClusterListingActions.clusterNodeSnackbarError({ error: errorResponse.error })); return of(ClusterListingActions.clusterNodeSnackbarError({ errorResponse }));
}) })
) )
) )
@ -319,8 +319,10 @@ export class ClusterListingEffects {
clusterNodeSnackbarError$ = createEffect(() => clusterNodeSnackbarError$ = createEffect(() =>
this.actions$.pipe( this.actions$.pipe(
ofType(ClusterListingActions.clusterNodeSnackbarError), ofType(ClusterListingActions.clusterNodeSnackbarError),
map((action) => action.error), map((action) => action.errorResponse),
switchMap((errorResponse) => of(ErrorActions.snackBarError({ error: errorResponse }))) switchMap((errorResponse) =>
of(ErrorActions.snackBarError({ error: this.errorHelper.getErrorString(errorResponse) }))
)
) )
); );

View File

@ -17,6 +17,7 @@
import { createAction, props } from '@ngrx/store'; import { createAction, props } from '@ngrx/store';
import { LoadCounterListingResponse, ResetCounterRequest, ResetCounterSuccess } from './index'; import { LoadCounterListingResponse, ResetCounterRequest, ResetCounterSuccess } from './index';
import { HttpErrorResponse } from '@angular/common/http';
const COUNTER_PREFIX = '[Counter Listing]'; const COUNTER_PREFIX = '[Counter Listing]';
@ -29,7 +30,7 @@ export const loadCountersSuccess = createAction(
export const counterListingApiError = createAction( export const counterListingApiError = createAction(
`${COUNTER_PREFIX} Load Counter Listing Error`, `${COUNTER_PREFIX} Load Counter Listing Error`,
props<{ error: string }>() props<{ errorResponse: HttpErrorResponse }>()
); );
export const promptCounterReset = createAction( export const promptCounterReset = createAction(

View File

@ -101,7 +101,7 @@ export class CounterListingEffects {
}) })
), ),
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of(CounterListingActions.counterListingApiError({ error: errorResponse.error })) of(CounterListingActions.counterListingApiError({ errorResponse }))
) )
) )
) )
@ -111,8 +111,10 @@ export class CounterListingEffects {
counterListingApiError$ = createEffect(() => counterListingApiError$ = createEffect(() =>
this.actions$.pipe( this.actions$.pipe(
ofType(CounterListingActions.counterListingApiError), ofType(CounterListingActions.counterListingApiError),
map((action) => action.error), map((action) => action.errorResponse),
switchMap((error) => of(ErrorActions.snackBarError({ error }))) switchMap((errorResponse) =>
of(ErrorActions.snackBarError({ error: this.errorHelper.getErrorString(errorResponse) }))
)
) )
); );
} }

View File

@ -72,7 +72,9 @@ export class FlowConfigurationHistoryListingEffects {
this.actions$.pipe( this.actions$.pipe(
ofType(HistoryActions.flowConfigurationHistorySnackbarError), ofType(HistoryActions.flowConfigurationHistorySnackbarError),
map((action) => action.errorResponse), map((action) => action.errorResponse),
switchMap((errorResponse) => of(ErrorActions.snackBarError({ error: errorResponse.error }))) switchMap((errorResponse) =>
of(ErrorActions.snackBarError({ error: this.errorHelper.getErrorString(errorResponse) }))
)
) )
); );

View File

@ -52,7 +52,7 @@ const routes: Routes = [
} }
] ]
}, },
{ path: '', component: RootGroupRedirector, canActivate: [rootGroupGuard] } { path: '', component: RootGroupRedirector, canActivate: [rootGroupGuard], pathMatch: 'full' }
]; ];
@NgModule({ @NgModule({

View File

@ -32,6 +32,7 @@ import * as ParameterActions from '../state/parameter/parameter.actions';
import { FlowService } from './flow.service'; import { FlowService } from './flow.service';
import { MEDIUM_DIALOG } from '../../../index'; import { MEDIUM_DIALOG } from '../../../index';
import { ClusterConnectionService } from '../../../service/cluster-connection.service'; import { ClusterConnectionService } from '../../../service/cluster-connection.service';
import { ErrorHelper } from '../../../service/error-helper.service';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@ -43,7 +44,8 @@ export class ParameterHelperService {
private flowService: FlowService, private flowService: FlowService,
private parameterService: ParameterService, private parameterService: ParameterService,
private clusterConnectionService: ClusterConnectionService, private clusterConnectionService: ClusterConnectionService,
private client: Client private client: Client,
private errorHelper: ErrorHelper
) {} ) {}
/** /**
@ -56,7 +58,9 @@ export class ParameterHelperService {
return this.flowService.getParameterContext(parameterContextId).pipe( return this.flowService.getParameterContext(parameterContextId).pipe(
take(1), take(1),
catchError((errorResponse: HttpErrorResponse) => { catchError((errorResponse: HttpErrorResponse) => {
this.store.dispatch(ErrorActions.snackBarError({ error: errorResponse.error })); this.store.dispatch(
ErrorActions.snackBarError({ error: this.errorHelper.getErrorString(errorResponse) })
);
// consider the error handled and allow the user to reattempt the action // consider the error handled and allow the user to reattempt the action
return EMPTY; return EMPTY;
@ -82,7 +86,9 @@ export class ParameterHelperService {
return (name: string, sensitive: boolean, value: string | null) => { return (name: string, sensitive: boolean, value: string | null) => {
return this.parameterService.getParameterContext(parameterContextId, false).pipe( return this.parameterService.getParameterContext(parameterContextId, false).pipe(
catchError((errorResponse: HttpErrorResponse) => { catchError((errorResponse: HttpErrorResponse) => {
this.store.dispatch(ErrorActions.snackBarError({ error: errorResponse.error })); this.store.dispatch(
ErrorActions.snackBarError({ error: this.errorHelper.getErrorString(errorResponse) })
);
// consider the error handled and allow the user to reattempt the action // consider the error handled and allow the user to reattempt the action
return EMPTY; return EMPTY;

View File

@ -27,6 +27,7 @@ import { ControllerServiceService } from '../controller-service.service';
import { HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse } from '@angular/common/http';
import { fullScreenError } from '../../../../state/error/error.actions'; import { fullScreenError } from '../../../../state/error/error.actions';
import { ClusterConnectionService } from '../../../../service/cluster-connection.service'; import { ClusterConnectionService } from '../../../../service/cluster-connection.service';
import { ErrorHelper } from '../../../../service/error-helper.service';
export const controllerServiceAdvancedUiParamsResolver: ResolveFn<AdvancedUiParams> = ( export const controllerServiceAdvancedUiParamsResolver: ResolveFn<AdvancedUiParams> = (
route: ActivatedRouteSnapshot route: ActivatedRouteSnapshot
@ -35,6 +36,7 @@ export const controllerServiceAdvancedUiParamsResolver: ResolveFn<AdvancedUiPara
const controllerServiceService: ControllerServiceService = inject(ControllerServiceService); const controllerServiceService: ControllerServiceService = inject(ControllerServiceService);
const client: Client = inject(Client); const client: Client = inject(Client);
const clusterConnectionService: ClusterConnectionService = inject(ClusterConnectionService); const clusterConnectionService: ClusterConnectionService = inject(ClusterConnectionService);
const errorHelper: ErrorHelper = inject(ErrorHelper);
// getting id parameter from activated route because ngrx router store // getting id parameter from activated route because ngrx router store
// is not initialized when this resolver executes // is not initialized when this resolver executes
@ -54,7 +56,7 @@ export const controllerServiceAdvancedUiParamsResolver: ResolveFn<AdvancedUiPara
fullScreenError({ fullScreenError({
errorDetail: { errorDetail: {
title: 'Unable to Open Advanced UI', title: 'Unable to Open Advanced UI',
message: errorResponse.error message: errorHelper.getErrorString(errorResponse)
} }
}) })
); );

View File

@ -27,12 +27,14 @@ import { Client } from '../../../../service/client.service';
import { fullScreenError } from '../../../../state/error/error.actions'; import { fullScreenError } from '../../../../state/error/error.actions';
import { HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse } from '@angular/common/http';
import { ClusterConnectionService } from '../../../../service/cluster-connection.service'; import { ClusterConnectionService } from '../../../../service/cluster-connection.service';
import { ErrorHelper } from '../../../../service/error-helper.service';
export const processorAdvancedUiParamsResolver: ResolveFn<AdvancedUiParams> = (route: ActivatedRouteSnapshot) => { export const processorAdvancedUiParamsResolver: ResolveFn<AdvancedUiParams> = (route: ActivatedRouteSnapshot) => {
const store: Store<NiFiState> = inject(Store); const store: Store<NiFiState> = inject(Store);
const flowService: FlowService = inject(FlowService); const flowService: FlowService = inject(FlowService);
const client: Client = inject(Client); const client: Client = inject(Client);
const clusterConnectionService: ClusterConnectionService = inject(ClusterConnectionService); const clusterConnectionService: ClusterConnectionService = inject(ClusterConnectionService);
const errorHelper: ErrorHelper = inject(ErrorHelper);
// getting id parameter from activated route because ngrx router store // getting id parameter from activated route because ngrx router store
// is not initialized when this resolver executes // is not initialized when this resolver executes
@ -52,7 +54,7 @@ export const processorAdvancedUiParamsResolver: ResolveFn<AdvancedUiParams> = (r
fullScreenError({ fullScreenError({
errorDetail: { errorDetail: {
title: 'Unable to Open Advanced UI', title: 'Unable to Open Advanced UI',
message: errorResponse.error message: errorHelper.getErrorString(errorResponse)
} }
}) })
); );

View File

@ -31,8 +31,8 @@ import { EditControllerService } from '../../../../ui/common/controller-service/
import { import {
ComponentType, ComponentType,
ControllerServiceReferencingComponent, ControllerServiceReferencingComponent,
OpenChangeComponentVersionDialogRequest,
EditControllerServiceDialogRequest, EditControllerServiceDialogRequest,
OpenChangeComponentVersionDialogRequest,
UpdateControllerServiceRequest UpdateControllerServiceRequest
} from '../../../../state/shared'; } from '../../../../state/shared';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
@ -153,7 +153,9 @@ export class ControllerServicesEffects {
), ),
catchError((errorResponse: HttpErrorResponse) => { catchError((errorResponse: HttpErrorResponse) => {
this.dialog.closeAll(); this.dialog.closeAll();
return of(ErrorActions.snackBarError({ error: errorResponse.error })); return of(
ErrorActions.snackBarError({ error: this.errorHelper.getErrorString(errorResponse) })
);
}) })
) )
) )
@ -221,7 +223,11 @@ export class ControllerServicesEffects {
} }
}) })
); );
this.store.dispatch(ErrorActions.snackBarError({ error: errorResponse.error })); this.store.dispatch(
ErrorActions.snackBarError({
error: this.errorHelper.getErrorString(errorResponse)
})
);
} }
}) })
) )
@ -302,7 +308,11 @@ export class ControllerServicesEffects {
goTo(commands, 'Controller Service'); goTo(commands, 'Controller Service');
}, },
error: (errorResponse: HttpErrorResponse) => { error: (errorResponse: HttpErrorResponse) => {
this.store.dispatch(ErrorActions.snackBarError({ error: errorResponse.error })); this.store.dispatch(
ErrorActions.snackBarError({
error: this.errorHelper.getErrorString(errorResponse)
})
);
} }
}); });
}; };
@ -374,7 +384,7 @@ export class ControllerServicesEffects {
if (this.errorHelper.showErrorInContext(errorResponse.status)) { if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return of( return of(
ControllerServicesActions.controllerServicesBannerApiError({ ControllerServicesActions.controllerServicesBannerApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
); );
} else { } else {
@ -532,7 +542,7 @@ export class ControllerServicesEffects {
}) })
), ),
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of(ErrorActions.snackBarError({ error: errorResponse.error })) of(ErrorActions.snackBarError({ error: this.errorHelper.getErrorString(errorResponse) }))
) )
) )
) )
@ -574,7 +584,11 @@ export class ControllerServicesEffects {
), ),
tap({ tap({
error: (errorResponse: HttpErrorResponse) => { error: (errorResponse: HttpErrorResponse) => {
this.store.dispatch(ErrorActions.snackBarError({ error: errorResponse.error })); this.store.dispatch(
ErrorActions.snackBarError({
error: this.errorHelper.getErrorString(errorResponse)
})
);
} }
}) })
) )

View File

@ -2431,7 +2431,7 @@ export class FlowEffects {
this.store.dispatch( this.store.dispatch(
FlowActions.showOkDialog({ FlowActions.showOkDialog({
title: 'Failed to Replay Event', title: 'Failed to Replay Event',
message: errorResponse.error message: this.errorHelper.getErrorString(errorResponse)
}) })
); );
} }
@ -3172,18 +3172,18 @@ export class FlowEffects {
private bannerOrFullScreenError(errorResponse: HttpErrorResponse) { private bannerOrFullScreenError(errorResponse: HttpErrorResponse) {
if (this.errorHelper.showErrorInContext(errorResponse.status)) { if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return FlowActions.flowBannerError({ return FlowActions.flowBannerError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}); });
} else { } else {
return ErrorActions.fullScreenError(errorResponse.error); return this.errorHelper.fullScreenError(errorResponse);
} }
} }
private snackBarOrFullScreenError(errorResponse: HttpErrorResponse) { private snackBarOrFullScreenError(errorResponse: HttpErrorResponse) {
if (this.errorHelper.showErrorInContext(errorResponse.status)) { if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return FlowActions.flowSnackbarError({ error: errorResponse.error }); return FlowActions.flowSnackbarError({ error: this.errorHelper.getErrorString(errorResponse) });
} else { } else {
return ErrorActions.fullScreenError(errorResponse.error); return this.errorHelper.fullScreenError(errorResponse);
} }
} }

View File

@ -152,7 +152,7 @@ export class ManageRemotePortsEffects {
}); });
}), }),
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of(ErrorActions.snackBarError({ error: errorResponse.error })) of(ErrorActions.snackBarError({ error: this.errorHelper.getErrorString(errorResponse) }))
) )
); );
}) })
@ -181,7 +181,7 @@ export class ManageRemotePortsEffects {
}); });
}), }),
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of(ErrorActions.snackBarError({ error: errorResponse.error })) of(ErrorActions.snackBarError({ error: this.errorHelper.getErrorString(errorResponse) }))
) )
); );
}) })
@ -255,7 +255,7 @@ export class ManageRemotePortsEffects {
if (this.errorHelper.showErrorInContext(errorResponse.status)) { if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return of( return of(
ManageRemotePortsActions.remotePortsBannerApiError({ ManageRemotePortsActions.remotePortsBannerApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
); );
} else { } else {

View File

@ -26,13 +26,15 @@ import { isDefinedAndNotNull, ParameterContextUpdateRequest } from '../../../../
import { selectUpdateRequest } from './parameter.selectors'; import { selectUpdateRequest } from './parameter.selectors';
import { ParameterService } from '../../service/parameter.service'; import { ParameterService } from '../../service/parameter.service';
import { HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse } from '@angular/common/http';
import { ErrorHelper } from '../../../../service/error-helper.service';
@Injectable() @Injectable()
export class ParameterEffects { export class ParameterEffects {
constructor( constructor(
private actions$: Actions, private actions$: Actions,
private store: Store<CanvasState>, private store: Store<CanvasState>,
private parameterService: ParameterService private parameterService: ParameterService,
private errorHelper: ErrorHelper
) {} ) {}
submitParameterContextUpdateRequest$ = createEffect(() => submitParameterContextUpdateRequest$ = createEffect(() =>
@ -49,7 +51,11 @@ export class ParameterEffects {
}) })
), ),
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of(ParameterActions.parameterApiError({ error: errorResponse.error })) of(
ParameterActions.parameterApiError({
error: this.errorHelper.getErrorString(errorResponse)
})
)
) )
) )
) )
@ -99,7 +105,7 @@ export class ParameterEffects {
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
ParameterActions.parameterApiError({ ParameterActions.parameterApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
) )
) )
@ -135,7 +141,7 @@ export class ParameterEffects {
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
ParameterActions.parameterApiError({ ParameterActions.parameterApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
) )
) )

View File

@ -33,6 +33,8 @@ import { OkDialog } from '../../../../ui/common/ok-dialog/ok-dialog.component';
import { loadConnection, loadProcessGroup } from '../flow/flow.actions'; import { loadConnection, loadProcessGroup } from '../flow/flow.actions';
import { resetQueueState } from './queue.actions'; import { resetQueueState } from './queue.actions';
import { SMALL_DIALOG } from '../../../../index'; import { SMALL_DIALOG } from '../../../../index';
import { HttpErrorResponse } from '@angular/common/http';
import { ErrorHelper } from '../../../../service/error-helper.service';
@Injectable() @Injectable()
export class QueueEffects { export class QueueEffects {
@ -40,7 +42,8 @@ export class QueueEffects {
private actions$: Actions, private actions$: Actions,
private store: Store<CanvasState>, private store: Store<CanvasState>,
private queueService: QueueService, private queueService: QueueService,
private dialog: MatDialog private dialog: MatDialog,
private errorHelper: ErrorHelper
) {} ) {}
promptEmptyQueueRequest$ = createEffect( promptEmptyQueueRequest$ = createEffect(
@ -95,10 +98,10 @@ export class QueueEffects {
} }
}) })
), ),
catchError((error) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
QueueActions.queueApiError({ QueueActions.queueApiError({
error: error.error error: this.errorHelper.getErrorString(errorResponse)
}) })
) )
) )
@ -159,10 +162,10 @@ export class QueueEffects {
} }
}) })
), ),
catchError((error) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
QueueActions.queueApiError({ QueueActions.queueApiError({
error: error.error error: this.errorHelper.getErrorString(errorResponse)
}) })
) )
) )
@ -211,10 +214,10 @@ export class QueueEffects {
} }
}) })
), ),
catchError((error) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
QueueActions.queueApiError({ QueueActions.queueApiError({
error: error.error error: this.errorHelper.getErrorString(errorResponse)
}) })
) )
) )

View File

@ -25,6 +25,8 @@ import { Router } from '@angular/router';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { OkDialog } from '../../../../ui/common/ok-dialog/ok-dialog.component'; import { OkDialog } from '../../../../ui/common/ok-dialog/ok-dialog.component';
import { MEDIUM_DIALOG } from '../../../../index'; import { MEDIUM_DIALOG } from '../../../../index';
import { ErrorHelper } from '../../../../service/error-helper.service';
import { HttpErrorResponse } from '@angular/common/http';
@Injectable() @Injectable()
export class AccessEffects { export class AccessEffects {
@ -33,7 +35,8 @@ export class AccessEffects {
private authService: AuthService, private authService: AuthService,
private authStorage: AuthStorage, private authStorage: AuthStorage,
private router: Router, private router: Router,
private dialog: MatDialog private dialog: MatDialog,
private errorHelper: ErrorHelper
) {} ) {}
loadAccess$ = createEffect(() => loadAccess$ = createEffect(() =>
@ -49,12 +52,12 @@ export class AccessEffects {
} }
}) })
), ),
catchError((error) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
AccessActions.accessApiError({ AccessActions.accessApiError({
error: { error: {
title: 'Unable to check Access Status', title: 'Unable to check Access Status',
message: error.error message: this.errorHelper.getErrorString(errorResponse)
} }
}) })
) )
@ -77,7 +80,9 @@ export class AccessEffects {
} }
return AccessActions.verifyAccess(); return AccessActions.verifyAccess();
}), }),
catchError((error) => of(AccessActions.loginFailure({ failure: error.error }))) catchError((errorResponse: HttpErrorResponse) =>
of(AccessActions.loginFailure({ failure: this.errorHelper.getErrorString(errorResponse) }))
)
) )
) )
) )
@ -118,12 +123,12 @@ export class AccessEffects {
}); });
} }
}), }),
catchError((error) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
AccessActions.accessApiError({ AccessActions.accessApiError({
error: { error: {
title: 'Unable to log in', title: 'Unable to log in',
message: error.error message: this.errorHelper.getErrorString(errorResponse)
} }
}) })
) )

View File

@ -161,7 +161,7 @@ export class ParameterContextListingEffects {
if (this.errorHelper.showErrorInContext(errorResponse.status)) { if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return of( return of(
ParameterContextListingActions.parameterContextListingBannerApiError({ ParameterContextListingActions.parameterContextListingBannerApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
); );
} else { } else {
@ -230,7 +230,7 @@ export class ParameterContextListingEffects {
this.router.navigate(['/parameter-contexts']); this.router.navigate(['/parameter-contexts']);
return of( return of(
ParameterContextListingActions.parameterContextListingSnackbarApiError({ ParameterContextListingActions.parameterContextListingSnackbarApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
); );
}) })
@ -362,7 +362,7 @@ export class ParameterContextListingEffects {
if (this.errorHelper.showErrorInContext(errorResponse.status)) { if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return of( return of(
ParameterContextListingActions.parameterContextListingBannerApiError({ ParameterContextListingActions.parameterContextListingBannerApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
); );
} else { } else {
@ -425,7 +425,7 @@ export class ParameterContextListingEffects {
if (this.errorHelper.showErrorInContext(errorResponse.status)) { if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return of( return of(
ParameterContextListingActions.parameterContextListingBannerApiError({ ParameterContextListingActions.parameterContextListingBannerApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
); );
} else { } else {
@ -514,10 +514,10 @@ export class ParameterContextListingEffects {
} }
}) })
), ),
catchError((error) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
ParameterContextListingActions.parameterContextListingSnackbarApiError({ ParameterContextListingActions.parameterContextListingSnackbarApiError({
error: error.error error: this.errorHelper.getErrorString(errorResponse)
}) })
) )
) )

View File

@ -58,7 +58,7 @@ export class LineageEffects {
if (this.errorHelper.showErrorInContext(errorResponse.status)) { if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return of( return of(
LineageActions.lineageApiError({ LineageActions.lineageApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
); );
} else { } else {
@ -120,7 +120,7 @@ export class LineageEffects {
if (this.errorHelper.showErrorInContext(errorResponse.status)) { if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return of( return of(
LineageActions.lineageApiError({ LineageActions.lineageApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
); );
} else { } else {

View File

@ -27,8 +27,8 @@ import { Router } from '@angular/router';
import { OkDialog } from '../../../../ui/common/ok-dialog/ok-dialog.component'; import { OkDialog } from '../../../../ui/common/ok-dialog/ok-dialog.component';
import { ProvenanceService } from '../../service/provenance.service'; import { ProvenanceService } from '../../service/provenance.service';
import { import {
selectClusterNodeIdFromActiveProvenance,
selectActiveProvenanceId, selectActiveProvenanceId,
selectClusterNodeIdFromActiveProvenance,
selectProvenanceOptions, selectProvenanceOptions,
selectProvenanceRequest, selectProvenanceRequest,
selectTimeOffset selectTimeOffset
@ -113,7 +113,7 @@ export class ProvenanceEventListingEffects {
if (this.errorHelper.showErrorInContext(errorResponse.status)) { if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return of( return of(
ProvenanceEventListingActions.provenanceApiError({ ProvenanceEventListingActions.provenanceApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
); );
} else { } else {
@ -185,7 +185,7 @@ export class ProvenanceEventListingEffects {
if (this.errorHelper.showErrorInContext(errorResponse.status)) { if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return of( return of(
ProvenanceEventListingActions.provenanceApiError({ ProvenanceEventListingActions.provenanceApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
); );
} else { } else {
@ -248,7 +248,7 @@ export class ProvenanceEventListingEffects {
}) })
), ),
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of(ErrorActions.snackBarError({ error: errorResponse.error })) of(ErrorActions.snackBarError({ error: this.errorHelper.getErrorString(errorResponse) }))
) )
); );
} else { } else {
@ -371,7 +371,9 @@ export class ProvenanceEventListingEffects {
}, },
error: (errorResponse: HttpErrorResponse) => { error: (errorResponse: HttpErrorResponse) => {
this.store.dispatch( this.store.dispatch(
ErrorActions.snackBarError({ error: errorResponse.error }) ErrorActions.snackBarError({
error: this.errorHelper.getErrorString(errorResponse)
})
); );
} }
}); });
@ -379,7 +381,11 @@ export class ProvenanceEventListingEffects {
}, },
error: (errorResponse: HttpErrorResponse) => { error: (errorResponse: HttpErrorResponse) => {
if (this.errorHelper.showErrorInContext(errorResponse.status)) { if (this.errorHelper.showErrorInContext(errorResponse.status)) {
this.store.dispatch(ErrorActions.snackBarError({ error: errorResponse.error })); this.store.dispatch(
ErrorActions.snackBarError({
error: this.errorHelper.getErrorString(errorResponse)
})
);
} else { } else {
this.store.dispatch(this.errorHelper.fullScreenError(errorResponse)); this.store.dispatch(this.errorHelper.fullScreenError(errorResponse));
} }
@ -403,7 +409,11 @@ export class ProvenanceEventListingEffects {
this.router.navigate(this.getEventComponentLink(event.groupId, event.componentId)); this.router.navigate(this.getEventComponentLink(event.groupId, event.componentId));
}, },
error: (errorResponse: HttpErrorResponse) => { error: (errorResponse: HttpErrorResponse) => {
this.store.dispatch(ErrorActions.snackBarError({ error: errorResponse.error })); this.store.dispatch(
ErrorActions.snackBarError({
error: this.errorHelper.getErrorString(errorResponse)
})
);
} }
}); });
} else if (request.groupId && request.componentId) { } else if (request.groupId && request.componentId) {

View File

@ -113,7 +113,7 @@ export class QueueListingEffects {
if (this.errorHelper.showErrorInContext(errorResponse.status)) { if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return of( return of(
QueueListingActions.queueListingApiError({ QueueListingActions.queueListingApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
); );
} else { } else {
@ -181,7 +181,7 @@ export class QueueListingEffects {
if (this.errorHelper.showErrorInContext(errorResponse.status)) { if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return of( return of(
QueueListingActions.queueListingApiError({ QueueListingActions.queueListingApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
); );
} else { } else {
@ -221,7 +221,9 @@ export class QueueListingEffects {
if (listingRequest) { if (listingRequest) {
this.queueService.deleteQueueListingRequest(listingRequest).subscribe({ this.queueService.deleteQueueListingRequest(listingRequest).subscribe({
error: (errorResponse: HttpErrorResponse) => { error: (errorResponse: HttpErrorResponse) => {
this.store.dispatch(ErrorActions.snackBarError({ error: errorResponse.error })); this.store.dispatch(
ErrorActions.snackBarError({ error: this.errorHelper.getErrorString(errorResponse) })
);
} }
}); });
} }
@ -247,7 +249,7 @@ export class QueueListingEffects {
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
ErrorActions.snackBarError({ ErrorActions.snackBarError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
) )
) )

View File

@ -0,0 +1,28 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { NgModule } from '@angular/core';
import { RouteNotFound } from './route-not-found.component';
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [{ path: '', component: RouteNotFound }];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class RouteNotFoundRoutingModule {}

View File

@ -0,0 +1,22 @@
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<div class="error-background pt-24 pl-24 h-screen">
<page-content title="Route Not Found">
<div class="text-sm">The URL entered is not recognized as a supported route.</div>
</page-content>
</div>

View File

@ -0,0 +1,20 @@
/*!
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.error-background {
background: url(../../../../assets/icons/bg-error.png) left top no-repeat;
}

View File

@ -0,0 +1,39 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RouteNotFound } from './route-not-found.component';
describe('RouteNotFound', () => {
let component: RouteNotFound;
let fixture: ComponentFixture<RouteNotFound>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [RouteNotFound]
}).compileComponents();
fixture = TestBed.createComponent(RouteNotFound);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,25 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Component } from '@angular/core';
@Component({
selector: 'route-not-found',
templateUrl: './route-not-found.component.html',
styleUrl: './route-not-found.component.scss'
})
export class RouteNotFound {}

View File

@ -0,0 +1,29 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { NgModule } from '@angular/core';
import { RouteNotFound } from './route-not-found.component';
import { CommonModule } from '@angular/common';
import { RouteNotFoundRoutingModule } from './route-not-found-routing.module';
import { PageContent } from '../../../ui/common/page-content/page-content.component';
@NgModule({
declarations: [RouteNotFound],
exports: [RouteNotFound],
imports: [CommonModule, RouteNotFoundRoutingModule, PageContent]
})
export class RouteNotFoundModule {}

View File

@ -27,6 +27,7 @@ import { fullScreenError } from '../../../../state/error/error.actions';
import { ManagementControllerServiceService } from '../management-controller-service.service'; import { ManagementControllerServiceService } from '../management-controller-service.service';
import { selectService } from '../../state/management-controller-services/management-controller-services.selectors'; import { selectService } from '../../state/management-controller-services/management-controller-services.selectors';
import { ClusterConnectionService } from '../../../../service/cluster-connection.service'; import { ClusterConnectionService } from '../../../../service/cluster-connection.service';
import { ErrorHelper } from '../../../../service/error-helper.service';
export const controllerServiceAdvancedUiParamsResolver: ResolveFn<AdvancedUiParams> = ( export const controllerServiceAdvancedUiParamsResolver: ResolveFn<AdvancedUiParams> = (
route: ActivatedRouteSnapshot route: ActivatedRouteSnapshot
@ -37,6 +38,7 @@ export const controllerServiceAdvancedUiParamsResolver: ResolveFn<AdvancedUiPara
); );
const client: Client = inject(Client); const client: Client = inject(Client);
const clusterConnectionService: ClusterConnectionService = inject(ClusterConnectionService); const clusterConnectionService: ClusterConnectionService = inject(ClusterConnectionService);
const errorHelper: ErrorHelper = inject(ErrorHelper);
// getting id parameter from activated route because ngrx router store // getting id parameter from activated route because ngrx router store
// is not initialized when this resolver executes // is not initialized when this resolver executes
@ -56,7 +58,7 @@ export const controllerServiceAdvancedUiParamsResolver: ResolveFn<AdvancedUiPara
fullScreenError({ fullScreenError({
errorDetail: { errorDetail: {
title: 'Unable to Open Advanced UI', title: 'Unable to Open Advanced UI',
message: errorResponse.error message: errorHelper.getErrorString(errorResponse)
} }
}) })
); );

View File

@ -27,6 +27,7 @@ import { fullScreenError } from '../../../../state/error/error.actions';
import { ParameterProviderService } from '../parameter-provider.service'; import { ParameterProviderService } from '../parameter-provider.service';
import { selectParameterProvider } from '../../state/parameter-providers/parameter-providers.selectors'; import { selectParameterProvider } from '../../state/parameter-providers/parameter-providers.selectors';
import { ClusterConnectionService } from '../../../../service/cluster-connection.service'; import { ClusterConnectionService } from '../../../../service/cluster-connection.service';
import { ErrorHelper } from '../../../../service/error-helper.service';
export const parameterProviderAdvancedUiParamsResolver: ResolveFn<AdvancedUiParams> = ( export const parameterProviderAdvancedUiParamsResolver: ResolveFn<AdvancedUiParams> = (
route: ActivatedRouteSnapshot route: ActivatedRouteSnapshot
@ -35,6 +36,7 @@ export const parameterProviderAdvancedUiParamsResolver: ResolveFn<AdvancedUiPara
const parameterProviderService: ParameterProviderService = inject(ParameterProviderService); const parameterProviderService: ParameterProviderService = inject(ParameterProviderService);
const client: Client = inject(Client); const client: Client = inject(Client);
const clusterConnectionService: ClusterConnectionService = inject(ClusterConnectionService); const clusterConnectionService: ClusterConnectionService = inject(ClusterConnectionService);
const errorHelper: ErrorHelper = inject(ErrorHelper);
// getting id parameter from activated route because ngrx router store // getting id parameter from activated route because ngrx router store
// is not initialized when this resolver executes // is not initialized when this resolver executes
@ -54,7 +56,7 @@ export const parameterProviderAdvancedUiParamsResolver: ResolveFn<AdvancedUiPara
fullScreenError({ fullScreenError({
errorDetail: { errorDetail: {
title: 'Unable to Open Advanced UI', title: 'Unable to Open Advanced UI',
message: errorResponse.error message: errorHelper.getErrorString(errorResponse)
} }
}) })
); );

View File

@ -27,12 +27,14 @@ import { fullScreenError } from '../../../../state/error/error.actions';
import { ReportingTaskService } from '../reporting-task.service'; import { ReportingTaskService } from '../reporting-task.service';
import { selectTask } from '../../state/reporting-tasks/reporting-tasks.selectors'; import { selectTask } from '../../state/reporting-tasks/reporting-tasks.selectors';
import { ClusterConnectionService } from '../../../../service/cluster-connection.service'; import { ClusterConnectionService } from '../../../../service/cluster-connection.service';
import { ErrorHelper } from '../../../../service/error-helper.service';
export const reportingTaskAdvancedUiParamsResolver: ResolveFn<AdvancedUiParams> = (route: ActivatedRouteSnapshot) => { export const reportingTaskAdvancedUiParamsResolver: ResolveFn<AdvancedUiParams> = (route: ActivatedRouteSnapshot) => {
const store: Store<NiFiState> = inject(Store); const store: Store<NiFiState> = inject(Store);
const reportingTaskService: ReportingTaskService = inject(ReportingTaskService); const reportingTaskService: ReportingTaskService = inject(ReportingTaskService);
const client: Client = inject(Client); const client: Client = inject(Client);
const clusterConnectionService: ClusterConnectionService = inject(ClusterConnectionService); const clusterConnectionService: ClusterConnectionService = inject(ClusterConnectionService);
const errorHelper: ErrorHelper = inject(ErrorHelper);
// getting id parameter from activated route because ngrx router store // getting id parameter from activated route because ngrx router store
// is not initialized when this resolver executes // is not initialized when this resolver executes
@ -52,7 +54,7 @@ export const reportingTaskAdvancedUiParamsResolver: ResolveFn<AdvancedUiParams>
fullScreenError({ fullScreenError({
errorDetail: { errorDetail: {
title: 'Unable to Open Advanced UI', title: 'Unable to Open Advanced UI',
message: errorResponse.error message: errorHelper.getErrorString(errorResponse)
} }
}) })
); );

View File

@ -111,7 +111,9 @@ export class FlowAnalysisRulesEffects {
catchError((errorResponse: HttpErrorResponse) => { catchError((errorResponse: HttpErrorResponse) => {
this.dialog.closeAll(); this.dialog.closeAll();
return of( return of(
FlowAnalysisRuleActions.flowAnalysisRuleSnackbarApiError({ error: errorResponse.error }) FlowAnalysisRuleActions.flowAnalysisRuleSnackbarApiError({
error: this.errorHelper.getErrorString(errorResponse)
})
); );
}) })
) )
@ -196,7 +198,7 @@ export class FlowAnalysisRulesEffects {
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
FlowAnalysisRuleActions.flowAnalysisRuleSnackbarApiError({ FlowAnalysisRuleActions.flowAnalysisRuleSnackbarApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
) )
) )
@ -241,7 +243,7 @@ export class FlowAnalysisRulesEffects {
); );
this.store.dispatch( this.store.dispatch(
FlowAnalysisRuleActions.flowAnalysisRuleSnackbarApiError({ FlowAnalysisRuleActions.flowAnalysisRuleSnackbarApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
); );
} }
@ -349,7 +351,7 @@ export class FlowAnalysisRulesEffects {
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
FlowAnalysisRuleActions.flowAnalysisRuleBannerApiError({ FlowAnalysisRuleActions.flowAnalysisRuleBannerApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
) )
) )
@ -405,7 +407,7 @@ export class FlowAnalysisRulesEffects {
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
FlowAnalysisRuleActions.flowAnalysisRuleSnackbarApiError({ FlowAnalysisRuleActions.flowAnalysisRuleSnackbarApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
) )
) )
@ -446,7 +448,7 @@ export class FlowAnalysisRulesEffects {
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
FlowAnalysisRuleActions.flowAnalysisRuleSnackbarApiError({ FlowAnalysisRuleActions.flowAnalysisRuleSnackbarApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
) )
) )
@ -487,7 +489,11 @@ export class FlowAnalysisRulesEffects {
), ),
tap({ tap({
error: (errorResponse: HttpErrorResponse) => { error: (errorResponse: HttpErrorResponse) => {
this.store.dispatch(ErrorActions.snackBarError({ error: errorResponse.error })); this.store.dispatch(
ErrorActions.snackBarError({
error: this.errorHelper.getErrorString(errorResponse)
})
);
} }
}) })
) )

View File

@ -75,10 +75,10 @@ export class GeneralEffects {
} }
}) })
), ),
catchError((error) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
GeneralActions.controllerConfigApiError({ GeneralActions.controllerConfigApiError({
error: error.error error: this.errorHelper.getErrorString(errorResponse)
}) })
) )
) )

View File

@ -137,7 +137,7 @@ export class ManagementControllerServicesEffects {
this.dialog.closeAll(); this.dialog.closeAll();
return of( return of(
ManagementControllerServicesActions.managementControllerServicesSnackbarApiError({ ManagementControllerServicesActions.managementControllerServicesSnackbarApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
); );
}) })
@ -213,7 +213,7 @@ export class ManagementControllerServicesEffects {
); );
this.store.dispatch( this.store.dispatch(
ManagementControllerServicesActions.managementControllerServicesSnackbarApiError({ ManagementControllerServicesActions.managementControllerServicesSnackbarApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
); );
} }
@ -341,7 +341,7 @@ export class ManagementControllerServicesEffects {
if (this.errorHelper.showErrorInContext(errorResponse.status)) { if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return of( return of(
ManagementControllerServicesActions.managementControllerServicesBannerApiError({ ManagementControllerServicesActions.managementControllerServicesBannerApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
); );
} else { } else {
@ -495,7 +495,7 @@ export class ManagementControllerServicesEffects {
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
ManagementControllerServicesActions.managementControllerServicesSnackbarApiError({ ManagementControllerServicesActions.managementControllerServicesSnackbarApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
) )
) )
@ -534,7 +534,11 @@ export class ManagementControllerServicesEffects {
), ),
tap({ tap({
error: (errorResponse: HttpErrorResponse) => { error: (errorResponse: HttpErrorResponse) => {
this.store.dispatch(ErrorActions.snackBarError({ error: errorResponse.error })); this.store.dispatch(
ErrorActions.snackBarError({
error: this.errorHelper.getErrorString(errorResponse)
})
);
} }
}) })
) )

View File

@ -153,9 +153,11 @@ export class ParameterProvidersEffects {
} }
}) })
), ),
catchError((error: HttpErrorResponse) => { catchError((errorResponse: HttpErrorResponse) => {
this.dialog.closeAll(); this.dialog.closeAll();
return of(ErrorActions.snackBarError({ error: error.error })); return of(
ErrorActions.snackBarError({ error: this.errorHelper.getErrorString(errorResponse) })
);
}) })
) )
) )
@ -220,7 +222,9 @@ export class ParameterProvidersEffects {
} }
}) })
), ),
catchError((error) => of(ErrorActions.snackBarError({ error: error.error }))) catchError((errorResponse: HttpErrorResponse) =>
of(ErrorActions.snackBarError({ error: this.errorHelper.getErrorString(errorResponse) }))
)
) )
) )
) )
@ -284,7 +288,11 @@ export class ParameterProvidersEffects {
} }
}) })
); );
this.store.dispatch(ErrorActions.snackBarError({ error: errorResponse.error })); this.store.dispatch(
ErrorActions.snackBarError({
error: this.errorHelper.getErrorString(errorResponse)
})
);
} }
}) })
) )
@ -392,16 +400,16 @@ export class ParameterProvidersEffects {
} }
}) })
), ),
catchError((error: HttpErrorResponse) => { catchError((errorResponse: HttpErrorResponse) => {
if (this.errorHelper.showErrorInContext(error.status)) { if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return of( return of(
ParameterProviderActions.parameterProvidersBannerApiError({ ParameterProviderActions.parameterProvidersBannerApiError({
error: error.error error: this.errorHelper.getErrorString(errorResponse)
}) })
); );
} else { } else {
this.dialog.getDialogById(request.id)?.close('ROUTED'); this.dialog.getDialogById(request.id)?.close('ROUTED');
return of(this.errorHelper.fullScreenError(error)); return of(this.errorHelper.fullScreenError(errorResponse));
} }
}) })
) )
@ -437,8 +445,8 @@ export class ParameterProvidersEffects {
response: { parameterProvider: response } response: { parameterProvider: response }
}) })
), ),
catchError((error) => { catchError((errorResponse: HttpErrorResponse) => {
if (this.errorHelper.showErrorInContext(error.status)) { if (this.errorHelper.showErrorInContext(errorResponse.status)) {
this.store.dispatch( this.store.dispatch(
ParameterProviderActions.selectParameterProvider({ ParameterProviderActions.selectParameterProvider({
request: { request: {
@ -446,9 +454,11 @@ export class ParameterProvidersEffects {
} }
}) })
); );
return of(ErrorActions.snackBarError({ error: error.error })); return of(
ErrorActions.snackBarError({ error: this.errorHelper.getErrorString(errorResponse) })
);
} else { } else {
return of(ErrorActions.fullScreenError(error)); return of(this.errorHelper.fullScreenError(errorResponse));
} }
}) })
) )
@ -561,10 +571,10 @@ export class ParameterProvidersEffects {
} }
}) })
), ),
catchError((error) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
ParameterProviderActions.parameterProvidersBannerApiError({ ParameterProviderActions.parameterProvidersBannerApiError({
error: error.error error: this.errorHelper.getErrorString(errorResponse)
}) })
) )
) )
@ -621,10 +631,10 @@ export class ParameterProvidersEffects {
} }
}) })
), ),
catchError((error) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
ParameterProviderActions.parameterProvidersBannerApiError({ ParameterProviderActions.parameterProvidersBannerApiError({
error: error.error error: this.errorHelper.getErrorString(errorResponse)
}) })
) )
) )

View File

@ -117,7 +117,7 @@ export class RegistryClientsEffects {
this.dialog.closeAll(); this.dialog.closeAll();
return of( return of(
RegistryClientsActions.registryClientsSnackbarApiError({ RegistryClientsActions.registryClientsSnackbarApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
); );
}) })
@ -268,10 +268,10 @@ export class RegistryClientsEffects {
} }
}) })
), ),
catchError((error) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
RegistryClientsActions.registryClientsBannerApiError({ RegistryClientsActions.registryClientsBannerApiError({
error: error.error error: this.errorHelper.getErrorString(errorResponse)
}) })
) )
) )
@ -336,10 +336,10 @@ export class RegistryClientsEffects {
} }
}) })
), ),
catchError((error) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
RegistryClientsActions.registryClientsSnackbarApiError({ RegistryClientsActions.registryClientsSnackbarApiError({
error: error.error error: this.errorHelper.getErrorString(errorResponse)
}) })
) )
) )

View File

@ -112,7 +112,7 @@ export class ReportingTasksEffects {
this.dialog.closeAll(); this.dialog.closeAll();
return of( return of(
ReportingTaskActions.reportingTasksSnackbarApiError({ ReportingTaskActions.reportingTasksSnackbarApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
); );
}) })
@ -198,7 +198,7 @@ export class ReportingTasksEffects {
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
ReportingTaskActions.reportingTasksSnackbarApiError({ ReportingTaskActions.reportingTasksSnackbarApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
) )
) )
@ -254,7 +254,9 @@ export class ReportingTasksEffects {
}) })
); );
this.store.dispatch( this.store.dispatch(
ReportingTaskActions.reportingTasksSnackbarApiError({ error: errorResponse.error }) ReportingTaskActions.reportingTasksSnackbarApiError({
error: this.errorHelper.getErrorString(errorResponse)
})
); );
} }
}) })
@ -361,7 +363,7 @@ export class ReportingTasksEffects {
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
ReportingTaskActions.reportingTasksBannerApiError({ ReportingTaskActions.reportingTasksBannerApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
) )
) )
@ -403,7 +405,7 @@ export class ReportingTasksEffects {
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
ReportingTaskActions.reportingTasksSnackbarApiError({ ReportingTaskActions.reportingTasksSnackbarApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
) )
) )
@ -428,7 +430,7 @@ export class ReportingTasksEffects {
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
ReportingTaskActions.reportingTasksSnackbarApiError({ ReportingTaskActions.reportingTasksSnackbarApiError({
error: errorResponse.error error: this.errorHelper.getErrorString(errorResponse)
}) })
) )
) )
@ -465,7 +467,11 @@ export class ReportingTasksEffects {
), ),
tap({ tap({
error: (errorResponse: HttpErrorResponse) => { error: (errorResponse: HttpErrorResponse) => {
this.store.dispatch(ErrorActions.snackBarError({ error: errorResponse.error })); this.store.dispatch(
ErrorActions.snackBarError({
error: this.errorHelper.getErrorString(errorResponse)
})
);
} }
}) })
) )

View File

@ -58,7 +58,9 @@ export class ComponentClusterStatusEffects {
}), }),
catchError((errorResponse: HttpErrorResponse) => { catchError((errorResponse: HttpErrorResponse) => {
if (this.errorHelper.showErrorInContext(errorResponse.status)) { if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return of(ErrorActions.snackBarError({ error: errorResponse.error })); return of(
ErrorActions.snackBarError({ error: this.errorHelper.getErrorString(errorResponse) })
);
} }
return of(this.errorHelper.fullScreenError(errorResponse)); return of(this.errorHelper.fullScreenError(errorResponse));
}) })
@ -83,7 +85,9 @@ export class ComponentClusterStatusEffects {
}), }),
catchError((errorResponse: HttpErrorResponse) => { catchError((errorResponse: HttpErrorResponse) => {
if (this.errorHelper.showErrorInContext(errorResponse.status)) { if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return of(ErrorActions.snackBarError({ error: errorResponse.error })); return of(
ErrorActions.snackBarError({ error: this.errorHelper.getErrorString(errorResponse) })
);
} }
return of(this.errorHelper.fullScreenError(errorResponse)); return of(this.errorHelper.fullScreenError(errorResponse));
}) })

View File

@ -22,6 +22,7 @@ import { NiFiState } from '../../../../state';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import * as UserListingActions from './user-listing.actions'; import * as UserListingActions from './user-listing.actions';
import { selectTenant } from './user-listing.actions';
import { catchError, combineLatest, filter, from, map, mergeMap, of, switchMap, take, takeUntil, tap } from 'rxjs'; import { catchError, combineLatest, filter, from, map, mergeMap, of, switchMap, take, takeUntil, tap } from 'rxjs';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { UsersService } from '../../service/users.service'; import { UsersService } from '../../service/users.service';
@ -29,7 +30,6 @@ import { YesNoDialog } from '../../../../ui/common/yes-no-dialog/yes-no-dialog.c
import { EditTenantDialog } from '../../../../ui/common/edit-tenant/edit-tenant-dialog.component'; import { EditTenantDialog } from '../../../../ui/common/edit-tenant/edit-tenant-dialog.component';
import { selectSaving, selectStatus, selectUserGroups, selectUsers } from './user-listing.selectors'; import { selectSaving, selectStatus, selectUserGroups, selectUsers } from './user-listing.selectors';
import { EditTenantRequest, UserGroupEntity } from '../../../../state/shared'; import { EditTenantRequest, UserGroupEntity } from '../../../../state/shared';
import { selectTenant } from './user-listing.actions';
import { Client } from '../../../../service/client.service'; import { Client } from '../../../../service/client.service';
import { NiFiCommon } from '../../../../service/nifi-common.service'; import { NiFiCommon } from '../../../../service/nifi-common.service';
import { UserAccessPolicies } from '../../ui/user-listing/user-access-policies/user-access-policies.component'; import { UserAccessPolicies } from '../../ui/user-listing/user-access-policies/user-access-policies.component';
@ -160,7 +160,11 @@ export class UserListingEffects {
), ),
catchError((errorResponse: HttpErrorResponse) => { catchError((errorResponse: HttpErrorResponse) => {
this.dialog.closeAll(); this.dialog.closeAll();
return of(UserListingActions.usersApiSnackbarError({ error: errorResponse.error })); return of(
UserListingActions.usersApiSnackbarError({
error: this.errorHelper.getErrorString(errorResponse)
})
);
}) })
) )
) )
@ -287,7 +291,11 @@ export class UserListingEffects {
), ),
catchError((errorResponse: HttpErrorResponse) => { catchError((errorResponse: HttpErrorResponse) => {
this.dialog.closeAll(); this.dialog.closeAll();
return of(UserListingActions.usersApiSnackbarError({ error: errorResponse.error })); return of(
UserListingActions.usersApiSnackbarError({
error: this.errorHelper.getErrorString(errorResponse)
})
);
}) })
) )
) )
@ -413,7 +421,11 @@ export class UserListingEffects {
}) })
), ),
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of(UserListingActions.usersApiBannerError({ error: errorResponse.error })) of(
UserListingActions.usersApiBannerError({
error: this.errorHelper.getErrorString(errorResponse)
})
)
) )
) )
) )
@ -617,7 +629,11 @@ export class UserListingEffects {
}) })
), ),
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of(UserListingActions.usersApiBannerError({ error: errorResponse.error })) of(
UserListingActions.usersApiBannerError({
error: this.errorHelper.getErrorString(errorResponse)
})
)
) )
) )
) )
@ -708,7 +724,11 @@ export class UserListingEffects {
from(this.usersService.deleteUser(request.user)).pipe( from(this.usersService.deleteUser(request.user)).pipe(
map(() => UserListingActions.loadTenants()), map(() => UserListingActions.loadTenants()),
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of(UserListingActions.usersApiSnackbarError({ error: errorResponse.error })) of(
UserListingActions.usersApiSnackbarError({
error: this.errorHelper.getErrorString(errorResponse)
})
)
) )
) )
) )
@ -749,7 +769,11 @@ export class UserListingEffects {
from(this.usersService.deleteUserGroup(request.userGroup)).pipe( from(this.usersService.deleteUserGroup(request.userGroup)).pipe(
map(() => UserListingActions.loadTenants()), map(() => UserListingActions.loadTenants()),
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of(UserListingActions.usersApiSnackbarError({ error: errorResponse.error })) of(
UserListingActions.usersApiSnackbarError({
error: this.errorHelper.getErrorString(errorResponse)
})
)
) )
) )
) )

View File

@ -48,11 +48,11 @@ export class ErrorHelper {
break; break;
} }
if (this.nifiCommon.isBlank(errorResponse.error)) { if (errorResponse.status === 0 || !errorResponse.error) {
message = message =
'An error occurred communicating with NiFi. Please check the logs and fix any configuration issues before restarting.'; 'An error occurred communicating with NiFi. Please check the logs and fix any configuration issues before restarting.';
} else { } else {
message = errorResponse.error; message = this.getErrorString(errorResponse);
} }
return ErrorActions.fullScreenError({ return ErrorActions.fullScreenError({
@ -70,7 +70,7 @@ export class ErrorHelper {
handleLoadingError(status: string, errorResponse: HttpErrorResponse): Action { handleLoadingError(status: string, errorResponse: HttpErrorResponse): Action {
if (status === 'success') { if (status === 'success') {
if (this.showErrorInContext(errorResponse.status)) { if (this.showErrorInContext(errorResponse.status)) {
return ErrorActions.snackBarError({ error: errorResponse.error }); return ErrorActions.snackBarError({ error: this.getErrorString(errorResponse) });
} else { } else {
return this.fullScreenError(errorResponse); return this.fullScreenError(errorResponse);
} }
@ -78,4 +78,20 @@ export class ErrorHelper {
return this.fullScreenError(errorResponse); return this.fullScreenError(errorResponse);
} }
} }
getErrorString(errorResponse: HttpErrorResponse, prefix?: string): string {
let errorMessage = 'An unspecified error occurred.';
if (errorResponse.status !== 0) {
if (errorResponse.error) {
errorMessage = errorResponse.error;
} else {
errorMessage = errorResponse.message || `${errorResponse.status}`;
}
}
if (prefix) {
return `${prefix} - [${errorMessage}]`;
} else {
return errorMessage;
}
}
} }

View File

@ -40,6 +40,7 @@ import { Store } from '@ngrx/store';
import { snackBarError } from '../state/error/error.actions'; import { snackBarError } from '../state/error/error.actions';
import { HttpClient, HttpErrorResponse } from '@angular/common/http'; import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { LARGE_DIALOG, SMALL_DIALOG } from '../index'; import { LARGE_DIALOG, SMALL_DIALOG } from '../index';
import { ErrorHelper } from './error-helper.service';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@ -52,7 +53,8 @@ export class PropertyTableHelperService {
private dialog: MatDialog, private dialog: MatDialog,
private store: Store<NiFiState>, private store: Store<NiFiState>,
private extensionTypesService: ExtensionTypesService, private extensionTypesService: ExtensionTypesService,
private client: Client private client: Client,
private errorHelper: ErrorHelper
) {} ) {}
getComponentHistory(componentId: string): Observable<ComponentHistoryEntity> { getComponentHistory(componentId: string): Observable<ComponentHistoryEntity> {
@ -85,7 +87,14 @@ export class PropertyTableHelperService {
.pipe( .pipe(
take(1), take(1),
catchError((errorResponse: HttpErrorResponse) => { catchError((errorResponse: HttpErrorResponse) => {
this.store.dispatch(snackBarError({ error: errorResponse.error })); this.store.dispatch(
snackBarError({
error: this.errorHelper.getErrorString(
errorResponse,
`Failed to get property descriptor for ${dialogResponse.name}.`
)
})
);
// handle the error here to keep the observable alive so the // handle the error here to keep the observable alive so the
// user can attempt to create the property again // user can attempt to create the property again
@ -136,7 +145,9 @@ export class PropertyTableHelperService {
take(1), take(1),
tap({ tap({
error: (errorResponse: HttpErrorResponse) => { error: (errorResponse: HttpErrorResponse) => {
this.store.dispatch(snackBarError({ error: errorResponse.error })); this.store.dispatch(
snackBarError({ error: this.errorHelper.getErrorString(errorResponse) })
);
} }
}), }),
switchMap((implementingTypesResponse) => { switchMap((implementingTypesResponse) => {
@ -172,7 +183,10 @@ export class PropertyTableHelperService {
catchError((errorResponse: HttpErrorResponse) => { catchError((errorResponse: HttpErrorResponse) => {
this.store.dispatch( this.store.dispatch(
snackBarError({ snackBarError({
error: `Unable to create new Service: ${errorResponse.error}` error: this.errorHelper.getErrorString(
errorResponse,
`Unable to create new Service.`
)
}) })
); );
@ -200,7 +214,10 @@ export class PropertyTableHelperService {
this.store.dispatch( this.store.dispatch(
snackBarError({ snackBarError({
error: `Service created but unable to reload Property Descriptor: ${errorResponse.error}` error: this.errorHelper.getErrorString(
errorResponse,
'Service created but unable to reload Property Descriptor.'
)
}) })
); );
} }

View File

@ -25,13 +25,15 @@ import { HttpErrorResponse } from '@angular/common/http';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { AboutDialog } from '../../ui/common/about-dialog/about-dialog.component'; import { AboutDialog } from '../../ui/common/about-dialog/about-dialog.component';
import { MEDIUM_DIALOG } from '../../index'; import { MEDIUM_DIALOG } from '../../index';
import { ErrorHelper } from '../../service/error-helper.service';
@Injectable() @Injectable()
export class AboutEffects { export class AboutEffects {
constructor( constructor(
private actions$: Actions, private actions$: Actions,
private aboutService: AboutService, private aboutService: AboutService,
private dialog: MatDialog private dialog: MatDialog,
private errorHelper: ErrorHelper
) {} ) {}
loadAbout$ = createEffect(() => loadAbout$ = createEffect(() =>
@ -46,7 +48,7 @@ export class AboutEffects {
}) })
), ),
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of(ErrorActions.snackBarError({ error: errorResponse.error })) of(ErrorActions.snackBarError({ error: this.errorHelper.getErrorString(errorResponse) }))
) )
) )
); );

View File

@ -31,6 +31,7 @@ import * as ErrorActions from '../error/error.actions';
import { OkDialog } from '../../ui/common/ok-dialog/ok-dialog.component'; import { OkDialog } from '../../ui/common/ok-dialog/ok-dialog.component';
import { MEDIUM_DIALOG } from '../../index'; import { MEDIUM_DIALOG } from '../../index';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { ErrorHelper } from '../../service/error-helper.service';
@Injectable() @Injectable()
export class ClusterSummaryEffects { export class ClusterSummaryEffects {
@ -38,7 +39,8 @@ export class ClusterSummaryEffects {
private actions$: Actions, private actions$: Actions,
private clusterService: ClusterService, private clusterService: ClusterService,
private store: Store<ClusterSummaryState>, private store: Store<ClusterSummaryState>,
private dialog: MatDialog private dialog: MatDialog,
private errorHelper: ErrorHelper
) {} ) {}
loadClusterSummary$ = createEffect(() => loadClusterSummary$ = createEffect(() =>
@ -69,9 +71,10 @@ export class ClusterSummaryEffects {
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
ErrorActions.snackBarError({ ErrorActions.snackBarError({
error: `Failed to load cluster summary - [${ error: this.errorHelper.getErrorString(
errorResponse.error || errorResponse.status errorResponse,
}]` 'Failed to load cluster summary'
)
}) })
) )
) )
@ -148,9 +151,10 @@ export class ClusterSummaryEffects {
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
ErrorActions.snackBarError({ ErrorActions.snackBarError({
error: `Failed to search cluster summary - [${ error: this.errorHelper.getErrorString(
errorResponse.error || errorResponse.status errorResponse,
}]` 'Failed to search cluster summary'
)
}) })
) )
) )

View File

@ -31,6 +31,7 @@ import { isDefinedAndNotNull } from '../shared';
import { LARGE_DIALOG } from '../../index'; import { LARGE_DIALOG } from '../../index';
import * as ErrorActions from '../error/error.actions'; import * as ErrorActions from '../error/error.actions';
import { HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse } from '@angular/common/http';
import { ErrorHelper } from '../../service/error-helper.service';
@Injectable() @Injectable()
export class ComponentStateEffects { export class ComponentStateEffects {
@ -38,7 +39,8 @@ export class ComponentStateEffects {
private actions$: Actions, private actions$: Actions,
private store: Store<NiFiState>, private store: Store<NiFiState>,
private componentStateService: ComponentStateService, private componentStateService: ComponentStateService,
private dialog: MatDialog private dialog: MatDialog,
private errorHelper: ErrorHelper
) {} ) {}
getComponentStateAndOpenDialog$ = createEffect(() => getComponentStateAndOpenDialog$ = createEffect(() =>
@ -58,9 +60,10 @@ export class ComponentStateEffects {
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
ErrorActions.snackBarError({ ErrorActions.snackBarError({
error: `Failed to get the component state for ${request.componentName}. - [${ error: this.errorHelper.getErrorString(
errorResponse.error || errorResponse.status errorResponse,
}]` `Failed to get the component state for ${request.componentName}.`
)
}) })
) )
) )
@ -106,9 +109,10 @@ export class ComponentStateEffects {
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
ErrorActions.addBannerError({ ErrorActions.addBannerError({
error: `Failed to clear the component state. - [${ error: this.errorHelper.getErrorString(
errorResponse.error || errorResponse.status errorResponse,
}]` 'Failed to clear the component state.'
)
}) })
) )
) )
@ -135,9 +139,10 @@ export class ComponentStateEffects {
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
ErrorActions.addBannerError({ ErrorActions.addBannerError({
error: `Failed to reload the component state. - [${ error: this.errorHelper.getErrorString(
errorResponse.error || errorResponse.status errorResponse,
}]` 'Failed to reload the component state.'
)
}) })
) )
) )

View File

@ -29,6 +29,8 @@ import { ControllerServiceStateService } from '../../service/controller-service-
import { ControllerServiceEntity, ControllerServiceReferencingComponentEntity, isDefinedAndNotNull } from '../shared'; import { ControllerServiceEntity, ControllerServiceReferencingComponentEntity, isDefinedAndNotNull } from '../shared';
import { SetEnableRequest, SetEnableStep } from './index'; import { SetEnableRequest, SetEnableStep } from './index';
import { MEDIUM_DIALOG } from '../../index'; import { MEDIUM_DIALOG } from '../../index';
import { HttpErrorResponse } from '@angular/common/http';
import { ErrorHelper } from '../../service/error-helper.service';
@Injectable() @Injectable()
export class ControllerServiceStateEffects { export class ControllerServiceStateEffects {
@ -36,7 +38,8 @@ export class ControllerServiceStateEffects {
private actions$: Actions, private actions$: Actions,
private store: Store<NiFiState>, private store: Store<NiFiState>,
private dialog: MatDialog, private dialog: MatDialog,
private controllerServiceStateService: ControllerServiceStateService private controllerServiceStateService: ControllerServiceStateService,
private errorHelper: ErrorHelper
) {} ) {}
submitEnableRequest$ = createEffect(() => submitEnableRequest$ = createEffect(() =>
@ -102,12 +105,12 @@ export class ControllerServiceStateEffects {
} }
}) })
), ),
catchError((error) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
ControllerServiceActions.setEnableStepFailure({ ControllerServiceActions.setEnableStepFailure({
response: { response: {
step: setEnableRequest.currentStep, step: setEnableRequest.currentStep,
error: error.error error: this.errorHelper.getErrorString(errorResponse)
} }
}) })
) )
@ -157,12 +160,12 @@ export class ControllerServiceStateEffects {
previousStep: setEnableRequest.currentStep previousStep: setEnableRequest.currentStep
}) })
), ),
catchError((error) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
ControllerServiceActions.setEnableStepFailure({ ControllerServiceActions.setEnableStepFailure({
response: { response: {
step: setEnableRequest.currentStep, step: setEnableRequest.currentStep,
error: error.error error: this.errorHelper.getErrorString(errorResponse)
} }
}) })
) )
@ -228,12 +231,12 @@ export class ControllerServiceStateEffects {
} }
}) })
), ),
catchError((error) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
ControllerServiceActions.setEnableStepFailure({ ControllerServiceActions.setEnableStepFailure({
response: { response: {
step: setEnableRequest.currentStep, step: setEnableRequest.currentStep,
error: error.error error: this.errorHelper.getErrorString(errorResponse)
} }
}) })
) )
@ -274,12 +277,12 @@ export class ControllerServiceStateEffects {
} }
}) })
), ),
catchError((error) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
ControllerServiceActions.setEnableStepFailure({ ControllerServiceActions.setEnableStepFailure({
response: { response: {
step: setEnableRequest.currentStep, step: setEnableRequest.currentStep,
error: error.error error: this.errorHelper.getErrorString(errorResponse)
} }
}) })
) )

View File

@ -22,12 +22,14 @@ import { catchError, combineLatest, map, of, switchMap } from 'rxjs';
import { ExtensionTypesService } from '../../service/extension-types.service'; import { ExtensionTypesService } from '../../service/extension-types.service';
import * as ErrorActions from '../error/error.actions'; import * as ErrorActions from '../error/error.actions';
import { HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse } from '@angular/common/http';
import { ErrorHelper } from '../../service/error-helper.service';
@Injectable() @Injectable()
export class ExtensionTypesEffects { export class ExtensionTypesEffects {
constructor( constructor(
private actions$: Actions, private actions$: Actions,
private extensionTypesService: ExtensionTypesService private extensionTypesService: ExtensionTypesService,
private errorHelper: ErrorHelper
) {} ) {}
loadExtensionTypesForCanvas$ = createEffect(() => loadExtensionTypesForCanvas$ = createEffect(() =>
@ -119,7 +121,7 @@ export class ExtensionTypesEffects {
}) })
), ),
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of(ExtensionTypesActions.extensionTypesApiError({ error: errorResponse.error })) of(ExtensionTypesActions.extensionTypesApiError({ error: errorResponse }))
) )
) )
) )
@ -133,9 +135,10 @@ export class ExtensionTypesEffects {
switchMap((errorResponse: HttpErrorResponse) => switchMap((errorResponse: HttpErrorResponse) =>
of( of(
ErrorActions.snackBarError({ ErrorActions.snackBarError({
error: `Failed to load extension types. You may not be able to create new Processors, Controller Services, Reporting Tasks, Parameter Providers, or Flow Analysis Rules. - [${ error: this.errorHelper.getErrorString(
errorResponse.error || errorResponse.status errorResponse,
}]` 'Failed to load extension types. You may not be able to create new Processors, Controller Services, Reporting Tasks, Parameter Providers, or Flow Analysis Rules.'
)
}) })
) )
) )

View File

@ -22,12 +22,14 @@ import { catchError, from, map, of, switchMap } from 'rxjs';
import { FlowConfigurationService } from '../../service/flow-configuration.service'; import { FlowConfigurationService } from '../../service/flow-configuration.service';
import * as ErrorActions from '../error/error.actions'; import * as ErrorActions from '../error/error.actions';
import { HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse } from '@angular/common/http';
import { ErrorHelper } from '../../service/error-helper.service';
@Injectable() @Injectable()
export class FlowConfigurationEffects { export class FlowConfigurationEffects {
constructor( constructor(
private actions$: Actions, private actions$: Actions,
private flowConfigurationService: FlowConfigurationService private flowConfigurationService: FlowConfigurationService,
private errorHelper: ErrorHelper
) {} ) {}
loadFlowConfiguration$ = createEffect(() => loadFlowConfiguration$ = createEffect(() =>
@ -44,9 +46,10 @@ export class FlowConfigurationEffects {
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
ErrorActions.snackBarError({ ErrorActions.snackBarError({
error: `Failed to load Flow Configuration. - [${ error: this.errorHelper.getErrorString(
errorResponse.error || errorResponse.status errorResponse,
}]` 'Failed to load Flow Configuration.'
)
}) })
) )
) )

View File

@ -205,19 +205,20 @@ export class StatusHistoryEffects {
private bannerOrFullScreenError(errorResponse: HttpErrorResponse) { private bannerOrFullScreenError(errorResponse: HttpErrorResponse) {
if (this.errorHelper.showErrorInContext(errorResponse.status)) { if (this.errorHelper.showErrorInContext(errorResponse.status)) {
const error = `Failed to reload Status History. - [${errorResponse.error || errorResponse.status}]`; const error = this.errorHelper.getErrorString(errorResponse, 'Failed to reload Status History.');
return of(StatusHistoryActions.statusHistoryBannerError({ error })); return of(StatusHistoryActions.statusHistoryBannerError({ error }));
} else { } else {
return of(ErrorActions.fullScreenError(errorResponse.error)); return of(this.errorHelper.fullScreenError(errorResponse));
} }
} }
private snackBarOrFullScreenError(errorResponse: HttpErrorResponse) { private snackBarOrFullScreenError(errorResponse: HttpErrorResponse) {
if (this.errorHelper.showErrorInContext(errorResponse.status)) { if (this.errorHelper.showErrorInContext(errorResponse.status)) {
const error = `Failed to load Status History. - [${errorResponse.error || errorResponse.status}]`; const error = this.errorHelper.getErrorString(errorResponse, 'Failed to load Status History.');
return of(ErrorActions.snackBarError({ error })); return of(ErrorActions.snackBarError({ error }));
} else { } else {
return of(ErrorActions.fullScreenError(errorResponse.error)); return of(this.errorHelper.fullScreenError(errorResponse));
} }
} }
} }

View File

@ -28,6 +28,7 @@ import { SystemDiagnosticsDialog } from '../../ui/common/system-diagnostics-dial
import { LARGE_DIALOG } from '../../index'; import { LARGE_DIALOG } from '../../index';
import * as ErrorActions from '../error/error.actions'; import * as ErrorActions from '../error/error.actions';
import { HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse } from '@angular/common/http';
import { ErrorHelper } from '../../service/error-helper.service';
@Injectable() @Injectable()
export class SystemDiagnosticsEffects { export class SystemDiagnosticsEffects {
@ -35,7 +36,8 @@ export class SystemDiagnosticsEffects {
private actions$: Actions, private actions$: Actions,
private store: Store<NiFiState>, private store: Store<NiFiState>,
private systemDiagnosticsService: SystemDiagnosticsService, private systemDiagnosticsService: SystemDiagnosticsService,
private dialog: MatDialog private dialog: MatDialog,
private errorHelper: ErrorHelper
) {} ) {}
reloadSystemDiagnostics$ = createEffect(() => reloadSystemDiagnostics$ = createEffect(() =>
@ -52,22 +54,14 @@ export class SystemDiagnosticsEffects {
}) })
), ),
catchError((errorResponse: HttpErrorResponse) => { catchError((errorResponse: HttpErrorResponse) => {
if (request.errorStrategy === 'snackbar') { const error = this.errorHelper.getErrorString(
return of( errorResponse,
SystemDiagnosticsActions.systemDiagnosticsSnackbarError({ 'Failed to reload System Diagnostics.'
error: `Failed to reload System Diagnostics. - [${
errorResponse.error || errorResponse.status
}]`
})
);
}
return of(
SystemDiagnosticsActions.systemDiagnosticsBannerError({
error: `Failed to reload System Diagnostics. - [${
errorResponse.error || errorResponse.status
}]`
})
); );
if (request.errorStrategy === 'snackbar') {
return of(SystemDiagnosticsActions.systemDiagnosticsSnackbarError({ error }));
}
return of(SystemDiagnosticsActions.systemDiagnosticsBannerError({ error }));
}) })
) )
) )
@ -90,9 +84,10 @@ export class SystemDiagnosticsEffects {
catchError((errorResponse: HttpErrorResponse) => catchError((errorResponse: HttpErrorResponse) =>
of( of(
SystemDiagnosticsActions.systemDiagnosticsSnackbarError({ SystemDiagnosticsActions.systemDiagnosticsSnackbarError({
error: `Failed to load System Diagnostics. - [${ error: this.errorHelper.getErrorString(
errorResponse.error || errorResponse.status errorResponse,
}]` 'Failed to load System Diagnostics.'
)
}) })
) )
) )