Skip to content

Commit

Permalink
feat(deploy): display readable error message in log
Browse files Browse the repository at this point in the history
Closes #1426
  • Loading branch information
barmac authored and philippfromme committed Oct 4, 2019
1 parent fec12ec commit f21b8d0
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 66 deletions.
73 changes: 8 additions & 65 deletions client/src/plugins/deployment-tool/CamundaAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
* except in compliance with the MIT License.
*/

import { ConnectionErrorMessages } from './ErrorMessages';
import {
ConnectionError,
DeploymentError
} from './errors';

const FETCH_TIMEOUT = 5000;

Expand Down Expand Up @@ -63,9 +66,9 @@ export default class CamundaAPI {
};
}

const json = await this.safelyParse(response);
const body = await this.safelyParse(response);

throw responseError('Deployment failed', response, json);
throw new DeploymentError(response, body);
}

async checkConnection(details = {}) {
Expand All @@ -79,7 +82,7 @@ export default class CamundaAPI {
return;
}

throw connectionError(response);
throw new ConnectionError(response);
}

getHeaders(auth) {
Expand Down Expand Up @@ -118,7 +121,7 @@ export default class CamundaAPI {
response = {
url,
json: () => {
return { message: 'Fetch failed' };
return {};
}
};
}
Expand Down Expand Up @@ -146,63 +149,3 @@ export default class CamundaAPI {
}
}
}



// helpers //////////////

const parseError = 'ENGINE-09005 Could not parse BPMN process. Errors: \n*';

function responseError(message, response, details) {
const error = new Error(message);

error.details = details;
error.response = response;

// fix engine not exposing details
if (details && details.message && details.message.startsWith(parseError)) {
details.problems = details.message.substring(parseError.length).split(/\s?\n\*\s?/g);
details.message = 'ENGINE-09005 Could not parse BPMN process';
}

return error;
}

function connectionError(response) {
const error = new Error();

const errorMessageFromStatus = getStatusCodeErrorMessage(response);

if (errorMessageFromStatus) {
error.message = errorMessageFromStatus;

return error;
}

error.message = getNetworkErrorMessage(response);

return error;
}

function getStatusCodeErrorMessage(response) {
switch (response.status) {
case 401:
return ConnectionErrorMessages.unauthorized;
case 403:
return ConnectionErrorMessages.forbidden;
case 404:
return ConnectionErrorMessages.notFound;
case 500:
return ConnectionErrorMessages.internalServerError;
case 503:
return ConnectionErrorMessages.unavailable;
}
}

function getNetworkErrorMessage(response) {
if (!/^https?:\/\/localhost/.test(response.url) && !window.navigator.onLine) {
return ConnectionErrorMessages.noInternetConnection;
}

return ConnectionErrorMessages.unableToConnect;
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import {
Field
} from 'formik';

import { ConnectionErrorMessages } from './ErrorMessages';
import { ConnectionErrorMessages } from './errors';


const initialFormValues = {
Expand Down
2 changes: 2 additions & 0 deletions client/src/plugins/deployment-tool/DeploymentTool.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export default class DeploymentTool extends PureComponent {
// (3) Trigger deployment
// (3.1) Show deployment result (success or error)
const {
log,
displayNotification
} = this.props;

Expand All @@ -118,6 +119,7 @@ export default class DeploymentTool extends PureComponent {
content: 'See the log for further details.',
duration: 10000
});
log({ category: 'deploy-error', message: error.problems || error.message });
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,38 @@ export const ConnectionErrorMessages = {
internalServerError: 'Camunda is reporting an error. Please check the server status.',
unreachable: 'Camunda is reporting an error. Please check the server status.'
};


export default class ConnectionError extends Error {
constructor(response) {
super();

this.message = (
this.getStatusCodeErrorMessage(response) ||
this.getNetworkErrorMessage(response)
);
}

getStatusCodeErrorMessage(response) {
switch (response.status) {
case 401:
return ConnectionErrorMessages.unauthorized;
case 403:
return ConnectionErrorMessages.forbidden;
case 404:
return ConnectionErrorMessages.notFound;
case 500:
return ConnectionErrorMessages.internalServerError;
case 503:
return ConnectionErrorMessages.unavailable;
}
}

getNetworkErrorMessage(response) {
if (!/^https?:\/\/localhost/.test(response.url) && !window.navigator.onLine) {
return ConnectionErrorMessages.noInternetConnection;
}

return ConnectionErrorMessages.unableToConnect;
}
}
70 changes: 70 additions & 0 deletions client/src/plugins/deployment-tool/errors/DeploymentError.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership.
*
* Camunda licenses this file to you under the MIT; you may not use this file
* except in compliance with the MIT License.
*/

const DeploymentErrorMessages = {
noInternetConnection: 'Could not establish a network connection. Most likely your machine is not online right now.',
unableToConnect: 'Could not connect to the server. Did you run the engine?',
bpmnParsingError: 'Server could not parse the diagram. Please check log for errors.',
unauthorized: 'The deployment was unauthorized. Please use valid credentials.',
forbidden: 'The deployment was not permitted for your credentials. Please check your credentials.',
notFound: 'Could not connect to Camunda. Please check the endpoint URL.',
internalServerError: 'Camunda reported an unknown error. Please check the server status.',
serverUnavailable: 'Camunda is currently unavailable. Please try again later.'
};

const PARSE_ERROR = 'ENGINE-09005 Could not parse BPMN process. Errors:';


export default class DeploymentError extends Error {
constructor(response, body) {
super();

this.message = (
this.getCamundaBpmErrorMessage(body) ||
this.getStatusCodeErrorMessage(response) ||
this.getNetworkErrorMessage(response)
);

this.problems = this.getProblems(body);
}

getCamundaBpmErrorMessage(body) {
if (body && body.message && body.message.startsWith(PARSE_ERROR)) {
return DeploymentErrorMessages.bpmnParsingError;
}
}

getStatusCodeErrorMessage(response) {
switch (response.status) {
case 401:
return DeploymentErrorMessages.unauthorized;
case 403:
return DeploymentErrorMessages.forbidden;
case 404:
return DeploymentErrorMessages.notFound;
case 500:
return DeploymentErrorMessages.internalServerError;
case 503:
return DeploymentErrorMessages.serverUnavailable;
}
}

getNetworkErrorMessage(response) {
if (!/^https?:\/\/localhost/.test(response.url) && !window.navigator.onLine) {
return DeploymentErrorMessages.noInternetConnection;
}

return DeploymentErrorMessages.unableToConnect;
}

getProblems(body) {
return body.message;
}
}
18 changes: 18 additions & 0 deletions client/src/plugins/deployment-tool/errors/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership.
*
* Camunda licenses this file to you under the MIT; you may not use this file
* except in compliance with the MIT License.
*/

import ConnectionError, { ConnectionErrorMessages } from './ConnectionError';
import DeploymentError from './DeploymentError';

export {
ConnectionError,
ConnectionErrorMessages,
DeploymentError
};

0 comments on commit f21b8d0

Please sign in to comment.