Skip to content

Commit

Permalink
app: more elaborate error display
Browse files Browse the repository at this point in the history
  • Loading branch information
Rugvip committed Mar 23, 2020
1 parent a9aede1 commit bdaa603
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 9 deletions.
1 change: 1 addition & 0 deletions packages/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"dependencies": {
"@material-ui/core": "^4.9.1",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
"@spotify-backstage/cli": "^0.1.0",
"@spotify-backstage/core": "^0.1.0",
"@spotify-backstage/plugin-home-page": "^0.1.0",
Expand Down
4 changes: 3 additions & 1 deletion packages/app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ import { BackstageTheme, createApp } from '@spotify-backstage/core';
import React, { FC } from 'react';
import { BrowserRouter as Router } from 'react-router-dom';
import Root from './components/Root';
import ErrorDisplay from './components/ErrorDisplay';
import * as plugins from './plugins';
import apis from './apis';
import apis, { errorDialogForwarder } from './apis';

const useStyles = makeStyles(theme => ({
'@global': {
Expand Down Expand Up @@ -50,6 +51,7 @@ const App: FC<{}> = () => {
return (
<CssBaseline>
<ThemeProvider theme={BackstageTheme}>
<ErrorDisplay forwarder={errorDialogForwarder} />
<Router>
<Root>
<AppComponent />
Expand Down
10 changes: 2 additions & 8 deletions packages/app/src/apis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,11 @@
*/

import { ApiHolder, ApiRegistry, errorApiRef } from '@spotify-backstage/core';
import { ErrorDisplayForwarder } from './components/ErrorDisplay/ErrorDisplay';

const builder = ApiRegistry.builder();

class ErrorDialogForwarder {
post(error: Error) {
// eslint-disable-next-line no-console
console.error(`Received error, ${error}`);
}
}

export const errorDialogForwarder = new ErrorDialogForwarder();
export const errorDialogForwarder = new ErrorDisplayForwarder();

builder.add(errorApiRef, errorDialogForwarder);

Expand Down
84 changes: 84 additions & 0 deletions packages/app/src/components/ErrorDisplay/ErrorDisplay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright 2020 Spotify AB
*
* Licensed 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 React, { FC, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { Snackbar } from '@material-ui/core';
import { Alert } from '@material-ui/lab';
import { ErrorApi, ErrorContext } from '@spotify-backstage/core';

type SubscriberFunc = (error: Error) => void;
type Unsubscribe = () => void;

export class ErrorDisplayForwarder implements ErrorApi {
private readonly subscribers = new Set<SubscriberFunc>();

post(error: Error, context?: ErrorContext) {
if (context?.hidden) {
return;
}

this.subscribers.forEach(subscriber => subscriber(error));
}

subscribe(func: SubscriberFunc): Unsubscribe {
this.subscribers.add(func);

return () => {
this.subscribers.delete(func);
};
}
}

type Props = {
forwarder: ErrorDisplayForwarder;
};

const ErrorDisplay: FC<Props> = ({ forwarder }) => {
const [errors, setErrors] = useState<Array<Error>>([]);

useEffect(() => {
return forwarder.subscribe(error => setErrors(errs => errs.concat(error)));
}, [forwarder]);

if (errors.length === 0) {
return null;
}

const [firstError] = errors;

const handleClose = () => {
setErrors(errs => errs.filter(err => err !== firstError));
};

return (
<Snackbar
open
message={firstError.toString()}
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
>
<Alert onClose={handleClose} severity="error">
{firstError.toString()}
</Alert>
</Snackbar>
);
};

ErrorDisplay.propTypes = {
forwarder: PropTypes.instanceOf(ErrorDisplayForwarder).isRequired,
};

export default ErrorDisplay;
17 changes: 17 additions & 0 deletions packages/app/src/components/ErrorDisplay/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2020 Spotify AB
*
* Licensed 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.
*/

export { default } from './ErrorDisplay';

0 comments on commit bdaa603

Please sign in to comment.