frontend/app/common/ErrorViewComponent.jsx (74 lines of code) (raw):
import React from 'react';
import PropTypes from 'prop-types';
import {createStyles, Typography, withStyles} from "@material-ui/core";
const styles = (theme)=>createStyles({
errorText: {
color: theme.palette.error.dark
}
});
/**
* return a string containing text that describes the given axios error.
* @param error
* @param brief
* @returns {string}
*/
function formatError(error, brief) {
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
return `Server error ${error.response.status}: ` + ErrorViewComponent.bestErrorString(error.response.data, brief);
} else if (error.request) {
// The request was made but no response was received
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
// http.ClientRequest in node.js
console.error("Failed request: ", error.request);
return brief ? "No response" : "No response from server. See console log for more details."
} else {
// Something happened in setting up the request that triggered an Error
console.error('Axios error setting up request: ', error.message);
return brief ? "Couldn't send" : "Unable to set up request. See console log for more details."
}
}
class ErrorViewComponent extends React.Component {
static propTypes = {
error: PropTypes.object,
brief: PropTypes.bool
};
/* expects axios error response in props.error */
constructor(props){
super(props);
}
niceMakeString(someObject){
if(someObject.isObjectLike({})){
return this.dictToList(someObject);
} else if(Array.isArray(someObject)){
return someObject.reduce((acc, item)=> acc+this.niceMakeString(item), "");
} else {
return someObject.toString();
}
}
dictToList(dictObject){
return <ul>
{Object.keys(dictObject).map(key=>
<li>{key}: {this.niceMakeString(dictObject[key])}</li>
)}
</ul>
}
static bestErrorString(errorObj, brief){
if(brief) return "See console";
if(errorObj.hasOwnProperty("detail")) return JSON.stringify(errorObj.detail);
return errorObj.toString();
}
render(){
if(!this.props.error){
return <p className="error-text"/>
}
return <Typography className={this.props.classes.errorText}>
{
formatError(this.props.error, this.props.brief)
}
</Typography>
}
}
export {formatError};
export default withStyles(styles)(ErrorViewComponent);