Skip to content

Commit

Permalink
Add error alert type for non-catastrophic errors
Browse files Browse the repository at this point in the history
  • Loading branch information
alisman committed Nov 21, 2022
1 parent 707da42 commit c86e113
Show file tree
Hide file tree
Showing 17 changed files with 276 additions and 157 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@
"jquery": "3.6.0",
"jquery-migrate": "3.0.0",
"js-combinatorics": "^0.5.2",
"js-event-bus": "^1.1.1",
"json-fn": "^1.1.1",
"jsonpath": "^1.1.1",
"jspdf": "^1.3.3",
Expand Down
49 changes: 26 additions & 23 deletions src/AppStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ import client from 'shared/api/cbioportalClientInstance';
import { sendSentryMessage } from './shared/lib/tracking';
import { FeatureFlagStore } from 'shared/FeatureFlagStore';

export type SiteError = {
errorObj: any;
dismissed: boolean;
title?: string;
};
export class SiteError {
constructor(
public errorObj: any,
public displayType: 'alert' | 'site' = 'site',
public title?: string
) {}
}

export class AppStore {
constructor(
Expand All @@ -29,7 +31,7 @@ export class AppStore {

if (error.status && /400|500|403/.test(error.status)) {
sendSentryMessage('ERROR DIALOG SHOWN:' + error);
this.siteErrors.push({ errorObj: error, dismissed: false });
this.siteErrors.push(new SiteError(new Error(error)));
}
});
}
Expand All @@ -44,7 +46,9 @@ export class AppStore {

@observable private _appReady = false;

@observable siteErrors: SiteError[] = [];
siteErrors = observable.array<SiteError>();

alertErrors = observable.array<SiteError>();

@observable.ref userName: string | undefined = undefined;

Expand Down Expand Up @@ -76,30 +80,29 @@ export class AppStore {
}
}

@computed get undismissedSiteErrors() {
return _.filter(this.siteErrors.slice(), err => !err.dismissed);
}

@computed get isErrorCondition() {
return this.undismissedSiteErrors.length > 0;
return this.siteErrors.length > 0;
}

@action
public dismissErrors() {
this.siteErrors = this.siteErrors.map(err => {
err.dismissed = true;
return err;
});
this.siteErrors.clear();
}

@action public addError(err: String | SiteError) {
if (_.isString(err)) {
this.siteErrors.push({
errorObj: { message: err },
dismissed: false,
});
@action
public dismissError(err: SiteError) {
this.siteErrors.remove(err);
}

@action public addError(err: SiteError | string) {
if (typeof err === 'string') {
this.siteErrors.push(new SiteError(new Error(err)));
} else {
this.siteErrors.push({ errorObj: err, dismissed: false });
if (err.displayType === 'alert') {
this.alertErrors.push(err);
} else {
this.siteErrors.push(err);
}
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/appBootstrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import Container from 'appShell/App/Container';
import { IServerConfig } from 'config/IAppConfig';
import { initializeGenericAssayServerConfig } from 'shared/lib/GenericAssayUtils/GenericAssayConfig';
import { FeatureFlagStore } from 'shared/FeatureFlagStore';
import eventBus from 'shared/events/eventBus';

export interface ICBioWindow {
globalStores: {
Expand Down Expand Up @@ -163,6 +164,10 @@ const stores = {

browserWindow.globalStores = stores;

eventBus.on('error', err => {
stores.appStore.addError(err);
});

//@ts-ignore
const end = superagent.Request.prototype.end;

Expand Down
12 changes: 8 additions & 4 deletions src/appShell/App/Container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
import makeRoutes from 'routes';
import { AppContext } from 'cbioportal-frontend-commons';
import { IAppContext } from 'cbioportal-frontend-commons';
import { ErrorAlert } from 'shared/components/errorScreen/ErrorAlert';

interface IContainerProps {
location: Location;
Expand Down Expand Up @@ -123,7 +124,7 @@ export default class Container extends React.Component<IContainerProps, {}> {
<ErrorScreen
title={
formatErrorTitle(
this.appStore.undismissedSiteErrors
this.appStore.siteErrors
) ||
'Oops. There was an error retrieving data.'
}
Expand All @@ -133,16 +134,19 @@ export default class Container extends React.Component<IContainerProps, {}> {
</a>
}
errorLog={formatErrorLog(
this.appStore.undismissedSiteErrors
this.appStore.siteErrors
)}
errorMessages={formatErrorMessages(
this.appStore.undismissedSiteErrors
this.appStore.siteErrors
)}
/>
</div>
</Then>
<Else>
<div className="contentWrapper">{makeRoutes()}</div>
<div className="contentWrapper">
<ErrorAlert appStore={this.appStore} />
{makeRoutes()}
</div>
</Else>
</If>
</div>
Expand Down
2 changes: 0 additions & 2 deletions src/pages/groupComparison/GroupComparisonStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ import {
SampleFilter,
CancerStudy,
MutationMultipleStudyFilter,
SampleMolecularIdentifier,
GenePanelDataMultipleStudyFilter,
Mutation,
Gene,
GenePanelData,
} from 'cbioportal-ts-api-client';
import { action, observable, makeObservable, computed } from 'mobx';
import client from '../../shared/api/cbioportalClientInstance';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -754,11 +754,7 @@ export class PatientViewPageStore {
this.sampleId
),
onError: (err: Error) => {
this.appStore.siteErrors.push({
errorObj: err,
dismissed: false,
title: 'Samples / Patients not valid',
} as SiteError);
this.appStore.siteErrors.push(new SiteError(err));
},
},
[]
Expand Down Expand Up @@ -1668,6 +1664,7 @@ export class PatientViewPageStore {
return Promise.resolve([]);
}
},
onError: () => {},
},
[]
);
Expand Down Expand Up @@ -1715,6 +1712,7 @@ export class PatientViewPageStore {
return Promise.resolve({});
}
},
onError: () => {},
},
{}
);
Expand Down Expand Up @@ -2437,6 +2435,7 @@ export class PatientViewPageStore {
this.oncoKbAnnotatedGenes,
this.mutationData
),
onError: () => {},
},
ONCOKB_DEFAULT
);
Expand Down Expand Up @@ -2698,5 +2697,6 @@ export class PatientViewPageStore {
.value();
},
default: {},
onError: () => {},
});
}
18 changes: 12 additions & 6 deletions src/pages/resultsView/ResultsViewPageStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,10 +197,9 @@ import {
makeProfiledInClinicalAttributes,
} from '../../shared/components/oncoprint/ResultsViewOncoprintUtils';
import { annotateAlterationTypes } from '../../shared/lib/oql/annotateAlterationTypes';
import { ErrorMessages } from '../../shared/enums/ErrorEnums';
import sessionServiceClient from '../../shared/api/sessionServiceInstance';
import comparisonClient from '../../shared/api/comparisonGroupClientInstance';
import { AppStore } from '../../AppStore';
import { AppStore, SiteError } from '../../AppStore';
import { getNumSamples } from '../groupComparison/GroupComparisonUtils';
import autobind from 'autobind-decorator';
import {
Expand Down Expand Up @@ -300,6 +299,8 @@ import { getAlterationData } from 'shared/components/oncoprint/OncoprintUtils';
import { PageUserSession } from 'shared/userSession/PageUserSession';
import { PageType } from 'shared/userSession/PageType';
import { ClinicalTrackConfig } from 'shared/components/oncoprint/Oncoprint';
import eventBus from 'shared/events/eventBus';
import { ErrorMessages } from 'shared/errorMessages';

type Optional<T> =
| { isApplicable: true; value: T }
Expand Down Expand Up @@ -3997,7 +3998,11 @@ export class ResultsViewPageStore
}
return _.flatten(await Promise.all(promises));
},
onError: e => {
eventBus.emit('error', null, new SiteError(e));
},
},

[]
);

Expand Down Expand Up @@ -4596,7 +4601,7 @@ export class ResultsViewPageStore
) {
return genes;
} else {
throw new Error(ErrorMessages.InvalidGenes);
throw new Error(ErrorMessages.INVALID_GENES);
}
},
onResult: (genes: Gene[]) => {
Expand Down Expand Up @@ -5426,11 +5431,12 @@ export class ResultsViewPageStore
readonly oncoKbDataForOncoprint = remoteData<IOncoKbData | Error>(
{
await: () => [this.mutations, this.oncoKbAnnotatedGenes],
invoke: async () =>
fetchOncoKbDataForOncoprint(
invoke: async () => {
return await fetchOncoKbDataForOncoprint(
this.oncoKbAnnotatedGenes,
this.mutations
),
);
},
onError: (err: Error) => {
// fail silently, leave the error handling responsibility to the data consumer
},
Expand Down
27 changes: 27 additions & 0 deletions src/shared/components/errorScreen/ErrorAlert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import * as React from 'react';
import { AppStore } from 'AppStore';
import { observer } from 'mobx-react';
import styles from './errorScreen.module.scss';
import classNames from 'classnames';
import _ from 'lodash';

export const ErrorAlert: React.FunctionComponent<{
appStore: AppStore;
}> = observer(function({ appStore }) {
const errorGroups = _.groupBy(
appStore.alertErrors,
e => e.errorObj.message
);

return appStore.alertErrors.length ? (
<div className={styles.errorAlert}>
{_.map(errorGroups, (errors, message) => {
return <p>{message}</p>;
})}
<i
className={classNames(styles.dismissButton, 'fa', 'fa-close')}
onClick={() => appStore.alertErrors.clear()}
/>
</div>
) : null;
});
9 changes: 6 additions & 3 deletions src/shared/components/errorScreen/ErrorScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as React from 'react';
import _ from 'lodash';
import { getBrowserWindow } from 'cbioportal-frontend-commons';
import { observer } from 'mobx-react';
import './errorScreen.scss';
import styles from './errorScreen.module.scss';
import { getServerConfig } from 'config/config';
import { buildCBioPortalPageUrl } from 'shared/api/urls';
import { computed, makeObservable } from 'mobx';
Expand Down Expand Up @@ -57,8 +57,11 @@ export default class ErrorScreen extends React.Component<
const subject = 'cBioPortal user reported error';

return (
<div className={'errorScreen'}>
<a className={'errorLogo'} href={buildCBioPortalPageUrl('/')}>
<div className={styles.errorScreen}>
<a
className={styles.errorLogo}
href={buildCBioPortalPageUrl('/')}
>
<img
src={require('../../../globalStyles/images/cbioportal_logo.png')}
alt="cBioPortal Logo"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,25 @@
margin: 0 auto;
}
}

.errorAlert {
padding: 10px 30px 10px 10px;
background: $brand-danger;
color: #fff;
position: relative;

.dismissButton {
position: absolute;
right: 5px;
top: 10px;
cursor: pointer;

&:hover {
color: #eee;
}
}

p:last-of-type {
margin-bottom: 0 !important;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
declare const styles: {
readonly "dismissButton": string;
readonly "errorAlert": string;
readonly "errorLogo": string;
readonly "errorScreen": string;
};
export = styles;

3 changes: 0 additions & 3 deletions src/shared/enums/ErrorEnums.ts

This file was deleted.

5 changes: 5 additions & 0 deletions src/shared/errorMessages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const ErrorMessages = {
ONCOKB_LOAD_ERROR:
'Error loading OncoKB annotation data. UI may not accurately reflect Oncogenic status.',
INVALID_GENES: 'INVALID GENE SYMBOLS',
};
5 changes: 5 additions & 0 deletions src/shared/events/eventBus.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import EventBus from 'js-event-bus';

const eventBus = new EventBus();

export default eventBus;
Loading

0 comments on commit c86e113

Please sign in to comment.