/* Get whatever word is contained between the first two double quotes */ const getFirstWord = input => { const parts = /"([^"]*)"/.exec(input); if (parts === null) { return null; } return parts[1]; } /* Parse a GraphQL error message Sample message: "GraphQL error: Variable "$data" got invalid value {"meetingDate":"2018-08-07T06:05:51.704Z"}. In field "name": Expected "String!", found null. In field "stage": Expected "String!", found null. In field "addresses": Expected "[JSON]!", found null." */ const parseErrorMessage = message => { // note: optionally add .slice(1) at the end to get rid of the first error, which is not that helpful let fieldErrors = message.split('\n'); fieldErrors = fieldErrors.map(error => { // field name is whatever is between the first to double quotes const fieldName = getFirstWord(error); if (error.includes('found null')) { // missing field errors return { id: 'errors.required', path: fieldName, properties: { name: fieldName, }, } } else { // other generic GraphQL errors return { message: error } } }); return fieldErrors; } /* Errors can have the following properties stored on their `data` property: - id: used as an internationalization key, for example `errors.required` - path: for field-specific errors inside forms, the path of the field with the issue - properties: additional data. Will be passed to vulcan-i18n as values - message: if id cannot be used as i81n key, message will be used Scenario 1: normal error thrown with new Error(), put it in array and return it Scenario 2: multiple GraphQL errors stored on data.errors Scenario 3: single GraphQL error with data property Scenario 4: single GraphQL error with no data property */ export const getErrors = error => { // 1. wrap in array let errors = [error]; // if this is one or more GraphQL errors, extract and convert them if (error.graphQLErrors && error.graphQLErrors.length > 0) { // get graphQL error (see https://github.com/thebigredgeek/apollo-errors/issues/12) const graphQLError = error.graphQLErrors[0]; if (graphQLError.data && !_.isEmpty(graphQLError.data)) { if (graphQLError.data.errors) { // 2. there are multiple errors on the data.errors object errors = graphQLError.data && graphQLError.data.errors; } else { // 3. there is only one error errors = [graphQLError.data]; } } else { // 4. there is no data object, try to parse raw error message errors = parseErrorMessage(graphQLError.message); } } return errors; }