From 0507fc6d43fd6dd568b5a7dc1ec59026dc0ab68d Mon Sep 17 00:00:00 2001 From: xgui3783 <xgui3783@gmail.com> Date: Tue, 25 Aug 2020 12:56:51 +0200 Subject: [PATCH] bugfix: gracefully handle prv -> 404 #637 (#641) --- src/glue.spec.ts | 18 ++++++++++++++++++ src/glue.ts | 14 ++++++++++++-- .../databrowserModule/preview/preview.base.ts | 1 + 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/glue.spec.ts b/src/glue.spec.ts index 1ddec9282..884bd388c 100644 --- a/src/glue.spec.ts +++ b/src/glue.spec.ts @@ -316,6 +316,24 @@ describe('> glue.ts', () => { expect(colorMapMapSpy).toHaveBeenCalledWith(name, EnumColorMapName.VIRIDIS) expect(bgFlagSpy).toHaveBeenCalledWith(name, true) })) + + it('> if returns 404, should be handled gracefully', fakeAsync(() => { + + const ctrl = TestBed.inject(HttpTestingController) + const glue = TestBed.inject(DatasetPreviewGlue) + + const { datasetId, filename } = file3 + + const obs$ = glue.getDatasetPreviewFromId({ datasetId, filename }) + let expectedVal = 'defined' + obs$.subscribe(val => expectedVal = val) + tick(200) + + const req = ctrl.expectOne(`${DS_PREVIEW_URL}/${encodeURIComponent('minds/core/dataset/v1.0.0')}/${encodeURIComponent(datasetId)}/${encodeURIComponent(filename)}`) + req.flush(null, { status: 404, statusText: 'Not found' }) + + expect(expectedVal).toBeNull() + })) }) describe('> #actionOnWidget', () => { diff --git a/src/glue.ts b/src/glue.ts index baacec2a5..baeec8147 100644 --- a/src/glue.ts +++ b/src/glue.ts @@ -3,7 +3,7 @@ import { OnDestroy, Injectable, Optional, Inject, InjectionToken } from "@angula import { PreviewComponentWrapper, DatasetPreview, determinePreviewFileType, EnumPreviewFileTypes, IKgDataEntry, getKgSchemaIdFromFullId } from "./ui/databrowserModule/pure" import { Subscription, Observable, forkJoin, of, merge } from "rxjs" import { select, Store, ActionReducer, createAction, props, createSelector, Action } from "@ngrx/store" -import { startWith, map, shareReplay, pairwise, debounceTime, distinctUntilChanged, tap, switchMap, withLatestFrom, mapTo, switchMapTo, filter, skip } from "rxjs/operators" +import { startWith, map, shareReplay, pairwise, debounceTime, distinctUntilChanged, tap, switchMap, withLatestFrom, mapTo, switchMapTo, filter, skip, catchError } from "rxjs/operators" import { TypeActionToWidget, EnumActionToWidget, ACTION_TO_WIDGET_TOKEN } from "./widget" import { getIdObj } from 'common/util' import { MatDialogRef } from "@angular/material/dialog" @@ -24,6 +24,11 @@ const PREVIEW_FILE_TYPES_NO_UI = [ const DATASET_PREVIEW_ANNOTATION = `DATASET_PREVIEW_ANNOTATION` +const prvFilterNull = ({ prvToDismiss, prvToShow }) => ({ + prvToDismiss: prvToDismiss.filter(v => !!v), + prvToShow: prvToShow.filter(v => !!v), +}) + export const glueActionToggleDatasetPreview = createAction( '[glue] toggleDatasetPreview', props<{ datasetPreviewFile: IDatasetPreviewData }>() @@ -182,6 +187,7 @@ export class DatasetPreviewGlue implements IDatasetPreviewGlue, OnDestroy{ : of([]) }) }), + map(prvFilterNull), shareReplay(1) ) @@ -211,6 +217,7 @@ export class DatasetPreviewGlue implements IDatasetPreviewGlue, OnDestroy{ ? forkJoin(...arr.map(({ kgId, kgSchema, filename }) => this.getDatasetPreviewFromId({ datasetId: kgId, datasetSchema: kgSchema, filename }))) : of([]) ), + map(arr => arr.filter(item => !!item)), shareReplay(1), ) @@ -251,7 +258,8 @@ export class DatasetPreviewGlue implements IDatasetPreviewGlue, OnDestroy{ const cachedPrv$ = this.fetchedDatasetPreviewCache.get(dsPrvId) const filteredDsId = /[a-f0-9-]+$/.exec(datasetId) if (cachedPrv$) return cachedPrv$ - const filedetail$ = this.http.get(`${DS_PREVIEW_URL}/${encodeURIComponent(datasetSchema)}/${filteredDsId}/${encodeURIComponent(filename)}`, { responseType: 'json' }).pipe( + const url = `${DS_PREVIEW_URL}/${encodeURIComponent(datasetSchema)}/${filteredDsId}/${encodeURIComponent(filename)}` + const filedetail$ = this.http.get(url, { responseType: 'json' }).pipe( map(json => { return { ...json, @@ -259,6 +267,7 @@ export class DatasetPreviewGlue implements IDatasetPreviewGlue, OnDestroy{ datasetId } }), + catchError((_err, _obs) => of(null)) ) this.fetchedDatasetPreviewCache.set(dsPrvId, filedetail$) return filedetail$.pipe( @@ -340,6 +349,7 @@ export class DatasetPreviewGlue implements IDatasetPreviewGlue, OnDestroy{ map(prvToShow => ({ prvToDismiss: [], prvToShow })) ) ).pipe( + map(prvFilterNull), withLatestFrom(this.store$.pipe( select(state => state?.viewerState?.templateSelected || null), distinctUntilChanged(), diff --git a/src/ui/databrowserModule/preview/preview.base.ts b/src/ui/databrowserModule/preview/preview.base.ts index 1a9e4f7b1..7cf93b79b 100644 --- a/src/ui/databrowserModule/preview/preview.base.ts +++ b/src/ui/databrowserModule/preview/preview.base.ts @@ -37,6 +37,7 @@ export class PreviewBase implements OnChanges{ this.getDatasetPreviewFromId({ datasetSchema, datasetId, filename }) .subscribe( file => { + if (!file) return this.fetchingFlag = false this.file = file this.previewtype = determinePreviewFileType(file) -- GitLab