go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/milo/ui/src/common/components/error_handling/error_display.tsx (about) 1 // Copyright 2023 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 import { Alert, AlertTitle, Button } from '@mui/material'; 16 import { ReactNode, useEffect } from 'react'; 17 18 import { logging } from '@/common/tools/logging'; 19 import { genFeedbackUrl } from '@/common/tools/utils'; 20 21 export interface ErrorDisplayProps { 22 readonly error: Error; 23 /** 24 * When specified, render a highlighted instruction section, in addition to 25 * the error message. 26 */ 27 readonly instruction?: ReactNode; 28 readonly onTryAgain?: () => void; 29 } 30 31 export function ErrorDisplay({ 32 error, 33 instruction, 34 onTryAgain, 35 }: ErrorDisplayProps) { 36 useEffect(() => { 37 // Log the error to so we can inspect it in the browser console. 38 logging.error(error); 39 }, [error]); 40 41 return ( 42 <Alert severity="error" sx={{ '& > .MuiAlert-message': { flexGrow: 1 } }}> 43 <AlertTitle>Error</AlertTitle> 44 {instruction && ( 45 <div css={{ padding: '2px 5px', background: 'var(--warning-color)' }}> 46 {instruction} 47 </div> 48 )} 49 <pre 50 css={{ 51 whiteSpace: 'pre-wrap', 52 overflowWrap: 'break-word', 53 }} 54 > 55 {error.message} 56 </pre> 57 <Button 58 href={genFeedbackUrl(error.message, error.stack)} 59 target="_blank" 60 rel="noopener" 61 > 62 File a bug 63 </Button> 64 {onTryAgain && <Button onClick={() => onTryAgain()}>Try Again</Button>} 65 </Alert> 66 ); 67 }