[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 { RouterModule, Routes } from '@angular/router';
import { authenticationGuard } from './service/guard/authentication.guard';
import { RouteNotFound } from './pages/route-not-found/feature/route-not-found.component';
const routes: Routes = [
{
@ -101,6 +102,12 @@ const routes: Routes = [
canMatch: [authenticationGuard],
loadChildren: () =>
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 { HttpErrorResponse } from '@angular/common/http';
import { loadCurrentUser } from '../../../../state/current-user/current-user.actions';
import { ErrorHelper } from '../../../../service/error-helper.service';
@Injectable()
export class AccessPolicyEffects {
@ -45,7 +46,8 @@ export class AccessPolicyEffects {
private store: Store<NiFiState>,
private router: Router,
private accessPoliciesService: AccessPolicyService,
private dialog: MatDialog
private dialog: MatDialog,
private errorHelper: ErrorHelper
) {}
setAccessPolicy$ = createEffect(() =>
@ -128,7 +130,7 @@ export class AccessPolicyEffects {
return of(
AccessPolicyActions.accessPolicyApiBannerError({
response: {
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
}
})
);
@ -163,7 +165,7 @@ export class AccessPolicyEffects {
of(
AccessPolicyActions.accessPolicyApiBannerError({
response: {
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
}
})
)
@ -240,7 +242,7 @@ export class AccessPolicyEffects {
of(
AccessPolicyActions.accessPolicyApiBannerError({
response: {
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
}
})
)
@ -347,7 +349,7 @@ export class AccessPolicyEffects {
of(
AccessPolicyActions.accessPolicyApiBannerError({
response: {
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
}
})
)
@ -420,7 +422,7 @@ export class AccessPolicyEffects {
of(
AccessPolicyActions.accessPolicyApiBannerError({
response: {
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
}
})
)
@ -477,7 +479,7 @@ export class AccessPolicyEffects {
of(
AccessPolicyActions.accessPolicyApiBannerError({
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 { AccessPolicyService } from '../../service/access-policy.service';
import { HttpErrorResponse } from '@angular/common/http';
import { ErrorHelper } from '../../../../service/error-helper.service';
@Injectable()
export class PolicyComponentEffects {
constructor(
private actions$: Actions,
private accessPoliciesService: AccessPolicyService
private accessPoliciesService: AccessPolicyService,
private errorHelper: ErrorHelper
) {}
loadPolicyComponent$ = createEffect(() =>
@ -63,7 +65,7 @@ export class PolicyComponentEffects {
} else {
return of(
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 { AccessPolicyService } from '../../service/access-policy.service';
import { HttpErrorResponse } from '@angular/common/http';
import { ErrorHelper } from '../../../../service/error-helper.service';
@Injectable()
export class TenantsEffects {
constructor(
private actions$: Actions,
private accessPoliciesService: AccessPolicyService
private accessPoliciesService: AccessPolicyService,
private errorHelper: ErrorHelper
) {}
loadTenants$ = createEffect(() =>
@ -46,7 +48,7 @@ export class TenantsEffects {
catchError((errorResponse: HttpErrorResponse) =>
of(
ErrorActions.snackBarError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
)
)

View File

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

View File

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

View File

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

View File

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

View File

@ -72,7 +72,9 @@ export class FlowConfigurationHistoryListingEffects {
this.actions$.pipe(
ofType(HistoryActions.flowConfigurationHistorySnackbarError),
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({

View File

@ -32,6 +32,7 @@ import * as ParameterActions from '../state/parameter/parameter.actions';
import { FlowService } from './flow.service';
import { MEDIUM_DIALOG } from '../../../index';
import { ClusterConnectionService } from '../../../service/cluster-connection.service';
import { ErrorHelper } from '../../../service/error-helper.service';
@Injectable({
providedIn: 'root'
@ -43,7 +44,8 @@ export class ParameterHelperService {
private flowService: FlowService,
private parameterService: ParameterService,
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(
take(1),
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
return EMPTY;
@ -82,7 +86,9 @@ export class ParameterHelperService {
return (name: string, sensitive: boolean, value: string | null) => {
return this.parameterService.getParameterContext(parameterContextId, false).pipe(
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
return EMPTY;

View File

@ -27,6 +27,7 @@ import { ControllerServiceService } from '../controller-service.service';
import { HttpErrorResponse } from '@angular/common/http';
import { fullScreenError } from '../../../../state/error/error.actions';
import { ClusterConnectionService } from '../../../../service/cluster-connection.service';
import { ErrorHelper } from '../../../../service/error-helper.service';
export const controllerServiceAdvancedUiParamsResolver: ResolveFn<AdvancedUiParams> = (
route: ActivatedRouteSnapshot
@ -35,6 +36,7 @@ export const controllerServiceAdvancedUiParamsResolver: ResolveFn<AdvancedUiPara
const controllerServiceService: ControllerServiceService = inject(ControllerServiceService);
const client: Client = inject(Client);
const clusterConnectionService: ClusterConnectionService = inject(ClusterConnectionService);
const errorHelper: ErrorHelper = inject(ErrorHelper);
// getting id parameter from activated route because ngrx router store
// is not initialized when this resolver executes
@ -54,7 +56,7 @@ export const controllerServiceAdvancedUiParamsResolver: ResolveFn<AdvancedUiPara
fullScreenError({
errorDetail: {
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 { HttpErrorResponse } from '@angular/common/http';
import { ClusterConnectionService } from '../../../../service/cluster-connection.service';
import { ErrorHelper } from '../../../../service/error-helper.service';
export const processorAdvancedUiParamsResolver: ResolveFn<AdvancedUiParams> = (route: ActivatedRouteSnapshot) => {
const store: Store<NiFiState> = inject(Store);
const flowService: FlowService = inject(FlowService);
const client: Client = inject(Client);
const clusterConnectionService: ClusterConnectionService = inject(ClusterConnectionService);
const errorHelper: ErrorHelper = inject(ErrorHelper);
// getting id parameter from activated route because ngrx router store
// is not initialized when this resolver executes
@ -52,7 +54,7 @@ export const processorAdvancedUiParamsResolver: ResolveFn<AdvancedUiParams> = (r
fullScreenError({
errorDetail: {
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 {
ComponentType,
ControllerServiceReferencingComponent,
OpenChangeComponentVersionDialogRequest,
EditControllerServiceDialogRequest,
OpenChangeComponentVersionDialogRequest,
UpdateControllerServiceRequest
} from '../../../../state/shared';
import { Router } from '@angular/router';
@ -153,7 +153,9 @@ export class ControllerServicesEffects {
),
catchError((errorResponse: HttpErrorResponse) => {
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');
},
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)) {
return of(
ControllerServicesActions.controllerServicesBannerApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
);
} else {
@ -532,7 +542,7 @@ export class ControllerServicesEffects {
})
),
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({
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(
FlowActions.showOkDialog({
title: 'Failed to Replay Event',
message: errorResponse.error
message: this.errorHelper.getErrorString(errorResponse)
})
);
}
@ -3172,18 +3172,18 @@ export class FlowEffects {
private bannerOrFullScreenError(errorResponse: HttpErrorResponse) {
if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return FlowActions.flowBannerError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
});
} else {
return ErrorActions.fullScreenError(errorResponse.error);
return this.errorHelper.fullScreenError(errorResponse);
}
}
private snackBarOrFullScreenError(errorResponse: HttpErrorResponse) {
if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return FlowActions.flowSnackbarError({ error: errorResponse.error });
return FlowActions.flowSnackbarError({ error: this.errorHelper.getErrorString(errorResponse) });
} else {
return ErrorActions.fullScreenError(errorResponse.error);
return this.errorHelper.fullScreenError(errorResponse);
}
}

View File

@ -152,7 +152,7 @@ export class ManageRemotePortsEffects {
});
}),
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) =>
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)) {
return of(
ManageRemotePortsActions.remotePortsBannerApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
);
} else {

View File

@ -26,13 +26,15 @@ import { isDefinedAndNotNull, ParameterContextUpdateRequest } from '../../../../
import { selectUpdateRequest } from './parameter.selectors';
import { ParameterService } from '../../service/parameter.service';
import { HttpErrorResponse } from '@angular/common/http';
import { ErrorHelper } from '../../../../service/error-helper.service';
@Injectable()
export class ParameterEffects {
constructor(
private actions$: Actions,
private store: Store<CanvasState>,
private parameterService: ParameterService
private parameterService: ParameterService,
private errorHelper: ErrorHelper
) {}
submitParameterContextUpdateRequest$ = createEffect(() =>
@ -49,7 +51,11 @@ export class ParameterEffects {
})
),
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) =>
of(
ParameterActions.parameterApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
)
)
@ -135,7 +141,7 @@ export class ParameterEffects {
catchError((errorResponse: HttpErrorResponse) =>
of(
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 { resetQueueState } from './queue.actions';
import { SMALL_DIALOG } from '../../../../index';
import { HttpErrorResponse } from '@angular/common/http';
import { ErrorHelper } from '../../../../service/error-helper.service';
@Injectable()
export class QueueEffects {
@ -40,7 +42,8 @@ export class QueueEffects {
private actions$: Actions,
private store: Store<CanvasState>,
private queueService: QueueService,
private dialog: MatDialog
private dialog: MatDialog,
private errorHelper: ErrorHelper
) {}
promptEmptyQueueRequest$ = createEffect(
@ -95,10 +98,10 @@ export class QueueEffects {
}
})
),
catchError((error) =>
catchError((errorResponse: HttpErrorResponse) =>
of(
QueueActions.queueApiError({
error: error.error
error: this.errorHelper.getErrorString(errorResponse)
})
)
)
@ -159,10 +162,10 @@ export class QueueEffects {
}
})
),
catchError((error) =>
catchError((errorResponse: HttpErrorResponse) =>
of(
QueueActions.queueApiError({
error: error.error
error: this.errorHelper.getErrorString(errorResponse)
})
)
)
@ -211,10 +214,10 @@ export class QueueEffects {
}
})
),
catchError((error) =>
catchError((errorResponse: HttpErrorResponse) =>
of(
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 { OkDialog } from '../../../../ui/common/ok-dialog/ok-dialog.component';
import { MEDIUM_DIALOG } from '../../../../index';
import { ErrorHelper } from '../../../../service/error-helper.service';
import { HttpErrorResponse } from '@angular/common/http';
@Injectable()
export class AccessEffects {
@ -33,7 +35,8 @@ export class AccessEffects {
private authService: AuthService,
private authStorage: AuthStorage,
private router: Router,
private dialog: MatDialog
private dialog: MatDialog,
private errorHelper: ErrorHelper
) {}
loadAccess$ = createEffect(() =>
@ -49,12 +52,12 @@ export class AccessEffects {
}
})
),
catchError((error) =>
catchError((errorResponse: HttpErrorResponse) =>
of(
AccessActions.accessApiError({
error: {
title: 'Unable to check Access Status',
message: error.error
message: this.errorHelper.getErrorString(errorResponse)
}
})
)
@ -77,7 +80,9 @@ export class AccessEffects {
}
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(
AccessActions.accessApiError({
error: {
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)) {
return of(
ParameterContextListingActions.parameterContextListingBannerApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
);
} else {
@ -230,7 +230,7 @@ export class ParameterContextListingEffects {
this.router.navigate(['/parameter-contexts']);
return of(
ParameterContextListingActions.parameterContextListingSnackbarApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
);
})
@ -362,7 +362,7 @@ export class ParameterContextListingEffects {
if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return of(
ParameterContextListingActions.parameterContextListingBannerApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
);
} else {
@ -425,7 +425,7 @@ export class ParameterContextListingEffects {
if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return of(
ParameterContextListingActions.parameterContextListingBannerApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
);
} else {
@ -514,10 +514,10 @@ export class ParameterContextListingEffects {
}
})
),
catchError((error) =>
catchError((errorResponse: HttpErrorResponse) =>
of(
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)) {
return of(
LineageActions.lineageApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
);
} else {
@ -120,7 +120,7 @@ export class LineageEffects {
if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return of(
LineageActions.lineageApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
);
} else {

View File

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

View File

@ -113,7 +113,7 @@ export class QueueListingEffects {
if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return of(
QueueListingActions.queueListingApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
);
} else {
@ -181,7 +181,7 @@ export class QueueListingEffects {
if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return of(
QueueListingActions.queueListingApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
);
} else {
@ -221,7 +221,9 @@ export class QueueListingEffects {
if (listingRequest) {
this.queueService.deleteQueueListingRequest(listingRequest).subscribe({
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) =>
of(
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 { selectService } from '../../state/management-controller-services/management-controller-services.selectors';
import { ClusterConnectionService } from '../../../../service/cluster-connection.service';
import { ErrorHelper } from '../../../../service/error-helper.service';
export const controllerServiceAdvancedUiParamsResolver: ResolveFn<AdvancedUiParams> = (
route: ActivatedRouteSnapshot
@ -37,6 +38,7 @@ export const controllerServiceAdvancedUiParamsResolver: ResolveFn<AdvancedUiPara
);
const client: Client = inject(Client);
const clusterConnectionService: ClusterConnectionService = inject(ClusterConnectionService);
const errorHelper: ErrorHelper = inject(ErrorHelper);
// getting id parameter from activated route because ngrx router store
// is not initialized when this resolver executes
@ -56,7 +58,7 @@ export const controllerServiceAdvancedUiParamsResolver: ResolveFn<AdvancedUiPara
fullScreenError({
errorDetail: {
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 { selectParameterProvider } from '../../state/parameter-providers/parameter-providers.selectors';
import { ClusterConnectionService } from '../../../../service/cluster-connection.service';
import { ErrorHelper } from '../../../../service/error-helper.service';
export const parameterProviderAdvancedUiParamsResolver: ResolveFn<AdvancedUiParams> = (
route: ActivatedRouteSnapshot
@ -35,6 +36,7 @@ export const parameterProviderAdvancedUiParamsResolver: ResolveFn<AdvancedUiPara
const parameterProviderService: ParameterProviderService = inject(ParameterProviderService);
const client: Client = inject(Client);
const clusterConnectionService: ClusterConnectionService = inject(ClusterConnectionService);
const errorHelper: ErrorHelper = inject(ErrorHelper);
// getting id parameter from activated route because ngrx router store
// is not initialized when this resolver executes
@ -54,7 +56,7 @@ export const parameterProviderAdvancedUiParamsResolver: ResolveFn<AdvancedUiPara
fullScreenError({
errorDetail: {
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 { selectTask } from '../../state/reporting-tasks/reporting-tasks.selectors';
import { ClusterConnectionService } from '../../../../service/cluster-connection.service';
import { ErrorHelper } from '../../../../service/error-helper.service';
export const reportingTaskAdvancedUiParamsResolver: ResolveFn<AdvancedUiParams> = (route: ActivatedRouteSnapshot) => {
const store: Store<NiFiState> = inject(Store);
const reportingTaskService: ReportingTaskService = inject(ReportingTaskService);
const client: Client = inject(Client);
const clusterConnectionService: ClusterConnectionService = inject(ClusterConnectionService);
const errorHelper: ErrorHelper = inject(ErrorHelper);
// getting id parameter from activated route because ngrx router store
// is not initialized when this resolver executes
@ -52,7 +54,7 @@ export const reportingTaskAdvancedUiParamsResolver: ResolveFn<AdvancedUiParams>
fullScreenError({
errorDetail: {
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) => {
this.dialog.closeAll();
return of(
FlowAnalysisRuleActions.flowAnalysisRuleSnackbarApiError({ error: errorResponse.error })
FlowAnalysisRuleActions.flowAnalysisRuleSnackbarApiError({
error: this.errorHelper.getErrorString(errorResponse)
})
);
})
)
@ -196,7 +198,7 @@ export class FlowAnalysisRulesEffects {
catchError((errorResponse: HttpErrorResponse) =>
of(
FlowAnalysisRuleActions.flowAnalysisRuleSnackbarApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
)
)
@ -241,7 +243,7 @@ export class FlowAnalysisRulesEffects {
);
this.store.dispatch(
FlowAnalysisRuleActions.flowAnalysisRuleSnackbarApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
);
}
@ -349,7 +351,7 @@ export class FlowAnalysisRulesEffects {
catchError((errorResponse: HttpErrorResponse) =>
of(
FlowAnalysisRuleActions.flowAnalysisRuleBannerApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
)
)
@ -405,7 +407,7 @@ export class FlowAnalysisRulesEffects {
catchError((errorResponse: HttpErrorResponse) =>
of(
FlowAnalysisRuleActions.flowAnalysisRuleSnackbarApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
)
)
@ -446,7 +448,7 @@ export class FlowAnalysisRulesEffects {
catchError((errorResponse: HttpErrorResponse) =>
of(
FlowAnalysisRuleActions.flowAnalysisRuleSnackbarApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
)
)
@ -487,7 +489,11 @@ export class FlowAnalysisRulesEffects {
),
tap({
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(
GeneralActions.controllerConfigApiError({
error: error.error
error: this.errorHelper.getErrorString(errorResponse)
})
)
)

View File

@ -137,7 +137,7 @@ export class ManagementControllerServicesEffects {
this.dialog.closeAll();
return of(
ManagementControllerServicesActions.managementControllerServicesSnackbarApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
);
})
@ -213,7 +213,7 @@ export class ManagementControllerServicesEffects {
);
this.store.dispatch(
ManagementControllerServicesActions.managementControllerServicesSnackbarApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
);
}
@ -341,7 +341,7 @@ export class ManagementControllerServicesEffects {
if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return of(
ManagementControllerServicesActions.managementControllerServicesBannerApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
);
} else {
@ -495,7 +495,7 @@ export class ManagementControllerServicesEffects {
catchError((errorResponse: HttpErrorResponse) =>
of(
ManagementControllerServicesActions.managementControllerServicesSnackbarApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
)
)
@ -534,7 +534,11 @@ export class ManagementControllerServicesEffects {
),
tap({
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();
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) => {
if (this.errorHelper.showErrorInContext(error.status)) {
catchError((errorResponse: HttpErrorResponse) => {
if (this.errorHelper.showErrorInContext(errorResponse.status)) {
return of(
ParameterProviderActions.parameterProvidersBannerApiError({
error: error.error
error: this.errorHelper.getErrorString(errorResponse)
})
);
} else {
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 }
})
),
catchError((error) => {
if (this.errorHelper.showErrorInContext(error.status)) {
catchError((errorResponse: HttpErrorResponse) => {
if (this.errorHelper.showErrorInContext(errorResponse.status)) {
this.store.dispatch(
ParameterProviderActions.selectParameterProvider({
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 {
return of(ErrorActions.fullScreenError(error));
return of(this.errorHelper.fullScreenError(errorResponse));
}
})
)
@ -561,10 +571,10 @@ export class ParameterProvidersEffects {
}
})
),
catchError((error) =>
catchError((errorResponse: HttpErrorResponse) =>
of(
ParameterProviderActions.parameterProvidersBannerApiError({
error: error.error
error: this.errorHelper.getErrorString(errorResponse)
})
)
)
@ -621,10 +631,10 @@ export class ParameterProvidersEffects {
}
})
),
catchError((error) =>
catchError((errorResponse: HttpErrorResponse) =>
of(
ParameterProviderActions.parameterProvidersBannerApiError({
error: error.error
error: this.errorHelper.getErrorString(errorResponse)
})
)
)

View File

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

View File

@ -112,7 +112,7 @@ export class ReportingTasksEffects {
this.dialog.closeAll();
return of(
ReportingTaskActions.reportingTasksSnackbarApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
);
})
@ -198,7 +198,7 @@ export class ReportingTasksEffects {
catchError((errorResponse: HttpErrorResponse) =>
of(
ReportingTaskActions.reportingTasksSnackbarApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
)
)
@ -254,7 +254,9 @@ export class ReportingTasksEffects {
})
);
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) =>
of(
ReportingTaskActions.reportingTasksBannerApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
)
)
@ -403,7 +405,7 @@ export class ReportingTasksEffects {
catchError((errorResponse: HttpErrorResponse) =>
of(
ReportingTaskActions.reportingTasksSnackbarApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
)
)
@ -428,7 +430,7 @@ export class ReportingTasksEffects {
catchError((errorResponse: HttpErrorResponse) =>
of(
ReportingTaskActions.reportingTasksSnackbarApiError({
error: errorResponse.error
error: this.errorHelper.getErrorString(errorResponse)
})
)
)
@ -465,7 +467,11 @@ export class ReportingTasksEffects {
),
tap({
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) => {
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));
})
@ -83,7 +85,9 @@ export class ComponentClusterStatusEffects {
}),
catchError((errorResponse: HttpErrorResponse) => {
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));
})

View File

@ -22,6 +22,7 @@ import { NiFiState } from '../../../../state';
import { Store } from '@ngrx/store';
import { Router } from '@angular/router';
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 { MatDialog } from '@angular/material/dialog';
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 { selectSaving, selectStatus, selectUserGroups, selectUsers } from './user-listing.selectors';
import { EditTenantRequest, UserGroupEntity } from '../../../../state/shared';
import { selectTenant } from './user-listing.actions';
import { Client } from '../../../../service/client.service';
import { NiFiCommon } from '../../../../service/nifi-common.service';
import { UserAccessPolicies } from '../../ui/user-listing/user-access-policies/user-access-policies.component';
@ -160,7 +160,11 @@ export class UserListingEffects {
),
catchError((errorResponse: HttpErrorResponse) => {
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) => {
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) =>
of(UserListingActions.usersApiBannerError({ error: errorResponse.error }))
of(
UserListingActions.usersApiBannerError({
error: this.errorHelper.getErrorString(errorResponse)
})
)
)
)
)
@ -617,7 +629,11 @@ export class UserListingEffects {
})
),
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(
map(() => UserListingActions.loadTenants()),
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(
map(() => UserListingActions.loadTenants()),
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;
}
if (this.nifiCommon.isBlank(errorResponse.error)) {
if (errorResponse.status === 0 || !errorResponse.error) {
message =
'An error occurred communicating with NiFi. Please check the logs and fix any configuration issues before restarting.';
} else {
message = errorResponse.error;
message = this.getErrorString(errorResponse);
}
return ErrorActions.fullScreenError({
@ -70,7 +70,7 @@ export class ErrorHelper {
handleLoadingError(status: string, errorResponse: HttpErrorResponse): Action {
if (status === 'success') {
if (this.showErrorInContext(errorResponse.status)) {
return ErrorActions.snackBarError({ error: errorResponse.error });
return ErrorActions.snackBarError({ error: this.getErrorString(errorResponse) });
} else {
return this.fullScreenError(errorResponse);
}
@ -78,4 +78,20 @@ export class ErrorHelper {
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 { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { LARGE_DIALOG, SMALL_DIALOG } from '../index';
import { ErrorHelper } from './error-helper.service';
@Injectable({
providedIn: 'root'
@ -52,7 +53,8 @@ export class PropertyTableHelperService {
private dialog: MatDialog,
private store: Store<NiFiState>,
private extensionTypesService: ExtensionTypesService,
private client: Client
private client: Client,
private errorHelper: ErrorHelper
) {}
getComponentHistory(componentId: string): Observable<ComponentHistoryEntity> {
@ -85,7 +87,14 @@ export class PropertyTableHelperService {
.pipe(
take(1),
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
// user can attempt to create the property again
@ -136,7 +145,9 @@ export class PropertyTableHelperService {
take(1),
tap({
error: (errorResponse: HttpErrorResponse) => {
this.store.dispatch(snackBarError({ error: errorResponse.error }));
this.store.dispatch(
snackBarError({ error: this.errorHelper.getErrorString(errorResponse) })
);
}
}),
switchMap((implementingTypesResponse) => {
@ -172,7 +183,10 @@ export class PropertyTableHelperService {
catchError((errorResponse: HttpErrorResponse) => {
this.store.dispatch(
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(
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 { AboutDialog } from '../../ui/common/about-dialog/about-dialog.component';
import { MEDIUM_DIALOG } from '../../index';
import { ErrorHelper } from '../../service/error-helper.service';
@Injectable()
export class AboutEffects {
constructor(
private actions$: Actions,
private aboutService: AboutService,
private dialog: MatDialog
private dialog: MatDialog,
private errorHelper: ErrorHelper
) {}
loadAbout$ = createEffect(() =>
@ -46,7 +48,7 @@ export class AboutEffects {
})
),
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 { MEDIUM_DIALOG } from '../../index';
import { MatDialog } from '@angular/material/dialog';
import { ErrorHelper } from '../../service/error-helper.service';
@Injectable()
export class ClusterSummaryEffects {
@ -38,7 +39,8 @@ export class ClusterSummaryEffects {
private actions$: Actions,
private clusterService: ClusterService,
private store: Store<ClusterSummaryState>,
private dialog: MatDialog
private dialog: MatDialog,
private errorHelper: ErrorHelper
) {}
loadClusterSummary$ = createEffect(() =>
@ -69,9 +71,10 @@ export class ClusterSummaryEffects {
catchError((errorResponse: HttpErrorResponse) =>
of(
ErrorActions.snackBarError({
error: `Failed to load cluster summary - [${
errorResponse.error || errorResponse.status
}]`
error: this.errorHelper.getErrorString(
errorResponse,
'Failed to load cluster summary'
)
})
)
)
@ -148,9 +151,10 @@ export class ClusterSummaryEffects {
catchError((errorResponse: HttpErrorResponse) =>
of(
ErrorActions.snackBarError({
error: `Failed to search cluster summary - [${
errorResponse.error || errorResponse.status
}]`
error: this.errorHelper.getErrorString(
errorResponse,
'Failed to search cluster summary'
)
})
)
)

View File

@ -31,6 +31,7 @@ import { isDefinedAndNotNull } from '../shared';
import { LARGE_DIALOG } from '../../index';
import * as ErrorActions from '../error/error.actions';
import { HttpErrorResponse } from '@angular/common/http';
import { ErrorHelper } from '../../service/error-helper.service';
@Injectable()
export class ComponentStateEffects {
@ -38,7 +39,8 @@ export class ComponentStateEffects {
private actions$: Actions,
private store: Store<NiFiState>,
private componentStateService: ComponentStateService,
private dialog: MatDialog
private dialog: MatDialog,
private errorHelper: ErrorHelper
) {}
getComponentStateAndOpenDialog$ = createEffect(() =>
@ -58,9 +60,10 @@ export class ComponentStateEffects {
catchError((errorResponse: HttpErrorResponse) =>
of(
ErrorActions.snackBarError({
error: `Failed to get the component state for ${request.componentName}. - [${
errorResponse.error || errorResponse.status
}]`
error: this.errorHelper.getErrorString(
errorResponse,
`Failed to get the component state for ${request.componentName}.`
)
})
)
)
@ -106,9 +109,10 @@ export class ComponentStateEffects {
catchError((errorResponse: HttpErrorResponse) =>
of(
ErrorActions.addBannerError({
error: `Failed to clear the component state. - [${
errorResponse.error || errorResponse.status
}]`
error: this.errorHelper.getErrorString(
errorResponse,
'Failed to clear the component state.'
)
})
)
)
@ -135,9 +139,10 @@ export class ComponentStateEffects {
catchError((errorResponse: HttpErrorResponse) =>
of(
ErrorActions.addBannerError({
error: `Failed to reload the component state. - [${
errorResponse.error || errorResponse.status
}]`
error: this.errorHelper.getErrorString(
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 { SetEnableRequest, SetEnableStep } from './index';
import { MEDIUM_DIALOG } from '../../index';
import { HttpErrorResponse } from '@angular/common/http';
import { ErrorHelper } from '../../service/error-helper.service';
@Injectable()
export class ControllerServiceStateEffects {
@ -36,7 +38,8 @@ export class ControllerServiceStateEffects {
private actions$: Actions,
private store: Store<NiFiState>,
private dialog: MatDialog,
private controllerServiceStateService: ControllerServiceStateService
private controllerServiceStateService: ControllerServiceStateService,
private errorHelper: ErrorHelper
) {}
submitEnableRequest$ = createEffect(() =>
@ -102,12 +105,12 @@ export class ControllerServiceStateEffects {
}
})
),
catchError((error) =>
catchError((errorResponse: HttpErrorResponse) =>
of(
ControllerServiceActions.setEnableStepFailure({
response: {
step: setEnableRequest.currentStep,
error: error.error
error: this.errorHelper.getErrorString(errorResponse)
}
})
)
@ -157,12 +160,12 @@ export class ControllerServiceStateEffects {
previousStep: setEnableRequest.currentStep
})
),
catchError((error) =>
catchError((errorResponse: HttpErrorResponse) =>
of(
ControllerServiceActions.setEnableStepFailure({
response: {
step: setEnableRequest.currentStep,
error: error.error
error: this.errorHelper.getErrorString(errorResponse)
}
})
)
@ -228,12 +231,12 @@ export class ControllerServiceStateEffects {
}
})
),
catchError((error) =>
catchError((errorResponse: HttpErrorResponse) =>
of(
ControllerServiceActions.setEnableStepFailure({
response: {
step: setEnableRequest.currentStep,
error: error.error
error: this.errorHelper.getErrorString(errorResponse)
}
})
)
@ -274,12 +277,12 @@ export class ControllerServiceStateEffects {
}
})
),
catchError((error) =>
catchError((errorResponse: HttpErrorResponse) =>
of(
ControllerServiceActions.setEnableStepFailure({
response: {
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 * as ErrorActions from '../error/error.actions';
import { HttpErrorResponse } from '@angular/common/http';
import { ErrorHelper } from '../../service/error-helper.service';
@Injectable()
export class ExtensionTypesEffects {
constructor(
private actions$: Actions,
private extensionTypesService: ExtensionTypesService
private extensionTypesService: ExtensionTypesService,
private errorHelper: ErrorHelper
) {}
loadExtensionTypesForCanvas$ = createEffect(() =>
@ -119,7 +121,7 @@ export class ExtensionTypesEffects {
})
),
catchError((errorResponse: HttpErrorResponse) =>
of(ExtensionTypesActions.extensionTypesApiError({ error: errorResponse.error }))
of(ExtensionTypesActions.extensionTypesApiError({ error: errorResponse }))
)
)
)
@ -133,9 +135,10 @@ export class ExtensionTypesEffects {
switchMap((errorResponse: HttpErrorResponse) =>
of(
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. - [${
errorResponse.error || errorResponse.status
}]`
error: this.errorHelper.getErrorString(
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 * as ErrorActions from '../error/error.actions';
import { HttpErrorResponse } from '@angular/common/http';
import { ErrorHelper } from '../../service/error-helper.service';
@Injectable()
export class FlowConfigurationEffects {
constructor(
private actions$: Actions,
private flowConfigurationService: FlowConfigurationService
private flowConfigurationService: FlowConfigurationService,
private errorHelper: ErrorHelper
) {}
loadFlowConfiguration$ = createEffect(() =>
@ -44,9 +46,10 @@ export class FlowConfigurationEffects {
catchError((errorResponse: HttpErrorResponse) =>
of(
ErrorActions.snackBarError({
error: `Failed to load Flow Configuration. - [${
errorResponse.error || errorResponse.status
}]`
error: this.errorHelper.getErrorString(
errorResponse,
'Failed to load Flow Configuration.'
)
})
)
)

View File

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