diff --git a/packages/core-components/src/layout/ErrorBoundary/ErrorBoundary.tsx b/packages/core-components/src/layout/ErrorBoundary/ErrorBoundary.tsx index 4134808311..189803de59 100644 --- a/packages/core-components/src/layout/ErrorBoundary/ErrorBoundary.tsx +++ b/packages/core-components/src/layout/ErrorBoundary/ErrorBoundary.tsx @@ -14,10 +14,12 @@ * limitations under the License. */ -import React, { ComponentClass, Component, ErrorInfo } from 'react'; +import { Button, CardContent, CardHeader } from '@material-ui/core'; +import React, { ComponentClass, Component, ErrorInfo, useState } from 'react'; +import { slackChannel as defaultSlackChannel } from '../constants'; type Props = { - slackChannel?: string; + slackChannel?: typeof defaultSlackChannel; onError?: (error: Error, errorInfo: string) => null; }; @@ -28,15 +30,54 @@ type State = { type EProps = { error?: Error; - slackChannel?: string; + slackChannel?: typeof defaultSlackChannel; children?: React.ReactNode; }; -const Error = ({ slackChannel }: EProps) => { +const Error = ({ slackChannel, error }: EProps) => { + const [isShowingTrace, setIsShowingTrace] = useState(false); return (
- Something went wrong here.{' '} - {slackChannel && <>Please contact {slackChannel} for help.} + + +

+ Error: {error?.message ?? 'No Further Info'} +

+
+ +
+ {isShowingTrace && ( +
+            
+              {error?.stack?.split('\n').map(line => (
+                <>
+                  {line}
+                  
+ + )) ?? ''} +
+
+ )} + {slackChannel && ( +

+ Please contact{' '} + + {slackChannel.name} + {' '} + for help. +

+ )} +
); }; diff --git a/packages/core-components/src/layout/InfoCard/InfoCard.tsx b/packages/core-components/src/layout/InfoCard/InfoCard.tsx index 9a64bfa6f3..5240c77486 100644 --- a/packages/core-components/src/layout/InfoCard/InfoCard.tsx +++ b/packages/core-components/src/layout/InfoCard/InfoCard.tsx @@ -28,6 +28,7 @@ import { import classNames from 'classnames'; import { ErrorBoundary } from '../ErrorBoundary'; import { BottomLink, BottomLinkProps } from '../BottomLink'; +import { slackChannel as defaultSlackChannel } from '../constants'; const useStyles = makeStyles(theme => ({ noPadding: { @@ -112,7 +113,7 @@ type Props = { subheader?: ReactNode; divider?: boolean; deepLink?: BottomLinkProps; - slackChannel?: string; + slackChannel?: typeof defaultSlackChannel; variant?: InfoCardVariants; style?: object; cardStyle?: object; @@ -133,7 +134,7 @@ export const InfoCard = ({ subheader, divider = true, deepLink, - slackChannel = '#backstage', + slackChannel = defaultSlackChannel, variant, children, headerStyle, diff --git a/packages/core-components/src/layout/TabbedCard/TabbedCard.tsx b/packages/core-components/src/layout/TabbedCard/TabbedCard.tsx index 6204182cb1..be906100d5 100644 --- a/packages/core-components/src/layout/TabbedCard/TabbedCard.tsx +++ b/packages/core-components/src/layout/TabbedCard/TabbedCard.tsx @@ -33,6 +33,7 @@ import { } from '@material-ui/core'; import { BottomLink, BottomLinkProps } from '../BottomLink'; import { ErrorBoundary } from '../ErrorBoundary'; +import { slackChannel as defaultSlackChannel } from '../constants'; const useTabsStyles = makeStyles(theme => ({ root: { @@ -52,7 +53,7 @@ const BoldHeader = withStyles(theme => ({ }))(CardHeader); type Props = { - slackChannel?: string; + slackChannel?: typeof defaultSlackChannel; children?: ReactElement[]; onChange?: (event: React.ChangeEvent<{}>, value: number | string) => void; title?: string; @@ -61,7 +62,7 @@ type Props = { }; const TabbedCard = ({ - slackChannel = '#backstage', + slackChannel = defaultSlackChannel, children, title, deepLink, diff --git a/packages/core/src/layout/constants.ts b/packages/core/src/layout/constants.ts new file mode 100644 index 0000000000..a7005fc5ce --- /dev/null +++ b/packages/core/src/layout/constants.ts @@ -0,0 +1,19 @@ +/* + * Copyright 2021 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 const slackChannel = { + name: '#backstage', + href: 'https://spotify.slack.com/archives/C54P1J36Z', +};