diff --git a/lib/common/errors.js b/lib/common/errors.js index 1e3663b..f7c6644 100644 --- a/lib/common/errors.js +++ b/lib/common/errors.js @@ -15,13 +15,13 @@ * the base error class */ class AppError extends Error { - constructor(instanceId, status, message) { + constructor(instanceId, status, message, lineNo) { super(); this.instanceId = instanceId; this.status = status; this.message = message || 'unknown exception'; - this.lineNo = -1; + this.lineNo = lineNo || -1; } } diff --git a/src/app/components/import-data-dialog/import-data-dialog.component.ts b/src/app/components/import-data-dialog/import-data-dialog.component.ts index a92c53b..e69596f 100644 --- a/src/app/components/import-data-dialog/import-data-dialog.component.ts +++ b/src/app/components/import-data-dialog/import-data-dialog.component.ts @@ -17,7 +17,7 @@ export class ImportDataDialogComponent implements OnInit { public instanceId = ''; public rawContent = ''; - public flushDB = true; + public flushDB = false; public opType = ''; public exportType = 'redis'; @@ -114,18 +114,12 @@ export class ImportDataDialogComponent implements OnInit { const totalRow = this.flushDB ? commands.length - 1 : commands.length; this.redisService.call(this.instanceId, commands).subscribe((rsp) => { - let numberOfSucceed = 0; - _.each(rsp, v => { - numberOfSucceed += (!!v && v.toString().toLowerCase().indexOf('err') < 0) ? 1 : 0; - }); - numberOfSucceed -= this.flushDB ? 1 : 0; - const numberOfFailed = totalRow - numberOfSucceed; - this.util.showMessage(`${numberOfSucceed} row${numberOfSucceed !== 1 ? 's were' : ' was'} imported - successfully, ${numberOfFailed} row${numberOfFailed !== 1 ? 's have' : ' has'} failed.`); + this.util.showMessage(`All rows were imported successfully.`); this.dialogRef.close(); this._store.dispatch(new ReqFetchTree({id: this.instanceId})); }, err => { - this.util.showMessage('Failed to import commands: ' + this.util.getErrorMessage(err)); + const errorLineNo = err.error.line - (this.flushDB ? 1 : 0); + this.util.showMessage(`The command on row ${errorLineNo} failed with error: ${this.util.getErrorMessage(err)}`); }); } } diff --git a/src/app/ngrx/effects/page-effect.ts b/src/app/ngrx/effects/page-effect.ts index fc948c1..3cae3c7 100644 --- a/src/app/ngrx/effects/page-effect.ts +++ b/src/app/ngrx/effects/page-effect.ts @@ -7,7 +7,6 @@ import {RedisService} from '../../services/redis.service'; import {PageActions, LoadedPage, ReqLoadRootPage} from '../actions/page-actions'; -import {RedisConnectFailed} from '../actions/redis-actions'; import {catchError, map, mergeMap} from 'rxjs/operators'; import {Injectable} from '@angular/core'; @@ -54,10 +53,6 @@ export class PageEffect { requestId: action['payload'].requestId, id: action['payload'].id }); - }), - catchError(() => { - const id = action['payload'].id; - return of( new RedisConnectFailed({id})); }) ); } diff --git a/src/app/ngrx/effects/redis-effect.ts b/src/app/ngrx/effects/redis-effect.ts index f6e34de..33977a7 100644 --- a/src/app/ngrx/effects/redis-effect.ts +++ b/src/app/ngrx/effects/redis-effect.ts @@ -7,7 +7,7 @@ import {of, Observable} from 'rxjs'; import {RedisService} from '../../services/redis.service'; -import {RedisActions, FetchedTree, RedisConnect, RedisConnectFailed, ReqFetchTree, ReqRedisConnect} from '../actions/redis-actions'; +import {RedisActions, FetchedTree, RedisConnect, ReqFetchTree, ReqRedisConnect} from '../actions/redis-actions'; import {catchError, map, mergeMap} from 'rxjs/operators'; import {Injectable} from '@angular/core'; import {Action} from '@ngrx/store'; @@ -24,7 +24,6 @@ export class RedisEffect { /** * send connect request to backend when dispatch "ReqRedisConnect" * and when backend returned, dispatch data to "RedisConnect" - * when backend return error, dispatch to "RedisConnectFailed" */ @Effect() connectRedis: Observable = this.actions$.pipe( @@ -36,18 +35,6 @@ export class RedisEffect { action['payload'].scb(data); } return new RedisConnect(data); - }), - catchError(() => { - if (action['payload'].fcb) { - action['payload'].fcb(action['payload'].instance); - } - if (action['payload'].instance) { - const id = action['payload'].instance.id; - const host = action['payload'].instance.serverModel.name; - const port = action['payload'].instance.serverModel.port; - this.util.showMessage(`Fail to connect Redis server at ${host}:${port}.`); - return of(new RedisConnectFailed({id})); - } }) ); } @@ -57,7 +44,6 @@ export class RedisEffect { /** * send fetch tree request to backend when dispatch "ReqFetchTree" * and when backend returned, dispatch data to "FetchedTree" - * when backend return error, dispatch to "RedisConnectFailed" */ @Effect() fetchTree: Observable = this.actions$.pipe( @@ -70,9 +56,6 @@ export class RedisEffect { action['payload'].scb(data); } return new FetchedTree({id, data}); - }), - catchError(() => { - return of( new RedisConnectFailed({id})); }) ); } diff --git a/src/app/ngrx/reducer/redis-reducer.ts b/src/app/ngrx/reducer/redis-reducer.ts index 7ad4e4d..6a99812 100644 --- a/src/app/ngrx/reducer/redis-reducer.ts +++ b/src/app/ngrx/reducer/redis-reducer.ts @@ -6,7 +6,7 @@ import {RedisActions} from '../actions/redis-actions'; import {RedisInstance} from '../../models/redis-instance'; import _ from 'lodash'; -const REDIS_INSTANCES_KEY = 'REDIS_INSTANCES_KEY'; +export const REDIS_INSTANCES_KEY = 'REDIS_INSTANCES_KEY'; const defaultState = [{serverModel: {name: 'default-local', ip: 'localhost', port: 6379, db: 0, password: ''}, id: uuid()}]; let initState = defaultState; @@ -75,6 +75,8 @@ export function reducer(state = initialState, action) { const i = getInstanceById(action.payload.id, state); i.status = 'failed'; i.working = false; + i.selected = false; + i.expanded = false; return state; } case RedisActions.RedisConnect: { diff --git a/src/app/services/http-helper.service.ts b/src/app/services/http-helper.service.ts index 975e2b9..f5c64d3 100755 --- a/src/app/services/http-helper.service.ts +++ b/src/app/services/http-helper.service.ts @@ -4,6 +4,13 @@ import {HttpClient, HttpHeaders} from '@angular/common/http'; import * as _ from 'lodash'; import {environment} from '../../environments/environment'; import {catchError, delay} from 'rxjs/operators'; +import {Store} from '@ngrx/store'; +import {MatDialog} from '@angular/material'; + +import {RedisConnectFailed} from '../ngrx/actions/redis-actions'; +import {CollapseCli} from '../ngrx/actions/cli-actions'; +import {REDIS_INSTANCES_KEY} from '../ngrx/reducer/redis-reducer'; +import {UtilService} from './util.service'; export const API_BASE_URL = environment.URI; @@ -12,8 +19,12 @@ export const API_BASE_URL = environment.URI; }) export class HttpHelperService { - constructor(private http: HttpClient) { - } + constructor( + private http: HttpClient, + private util: UtilService, + private _store: Store, + private dialogService: MatDialog + ) { } /** * Performs a request with `get` http method. @@ -45,8 +56,26 @@ export class HttpHelperService { * catches the auth error * @param error the error response */ - catchError(error: Response): Observable { - return throwError(error); + catchError(error: any): Observable { + const err = error.error; + if (err.code === 500) { + const instancesString = localStorage.getItem(REDIS_INSTANCES_KEY); + const instances = instancesString ? JSON.parse(instancesString) : []; + const instance = _.find(instances, {'id': err.instanceId}); + if (instance) { + const id = instance.id; + const host = instance.serverModel.name; + const port = instance.serverModel.port; + // reset UI if redis connection fails + this.dialogService.closeAll(); + this.util.showMessage(`Failed to connect Redis server at ${host}:${port}.`); + this._store.dispatch(new RedisConnectFailed({id})); + this._store.dispatch(new CollapseCli()); + } + return of(); + } else { + return throwError(error); + } } /**