Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions packages/node-cli/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -286,11 +286,13 @@
"SDK_DOWNLOAD_SERVICE_GET_TIMEOUT": "GET request timeout.",
"SDK_DOWNLOAD_SERVICE_WRONG_DOWNLOAD_URL_PROTOCOL": "Invalid SDK jar file download url protocol. Only http: or https: are allowed.",

"DEV_ASSIST_PROXY_SERVICE_ERROR_MISSING_AUTH_ID": "It looks like we're missing your auth ID. Add it and we'll continue.",
"DEV_ASSIST_PROXY_SERVICE_ERROR_MISSING_PORT": "It looks like we're missing the port. Enter it and we'll continue.",
"DEV_ASSIST_PROXY_SERVICE_ERROR_PORT_MUST_BE_NUMBER" : "The required parameter port must be a number. Correct it and we'll continue.",
"DEV_ASSIST_PROXY_SERVICE_NOT_EXISTING_AUTH_ID" : "We couldn't find the auth ID \"{0}\". Check it and we'll continue.",
"DEV_ASSIST_PROXY_SERVICE_NEED_TO_REAUTHENTICATE" : "Manual authentication is needed. Sign in again to continue.",
"SUITECLOUD_AUTH_PROXY_SERVICE_ERROR_MISSING_AUTH_ID": "It looks like we're missing your auth ID. Add it and we'll continue.",
"SUITECLOUD_AUTH_PROXY_SERVICE_ERROR_MISSING_PORT": "It looks like we're missing the port. Enter it and we'll continue.",
"SUITECLOUD_AUTH_PROXY_SERVICE_ERROR_PORT_MUST_BE_NUMBER" : "The required parameter port must be a number. Correct it and we'll continue.",
"SUITECLOUD_AUTH_PROXY_SERVICE_NOT_EXISTING_AUTH_ID" : "We couldn't find the auth ID \"{0}\". Check it and we'll continue.",
"SUITECLOUD_AUTH_PROXY_SERVICE_NEED_TO_REAUTHENTICATE" : "Manual authentication is needed. Sign in again to continue.",
"SUITECLOUD_AUTH_PROXY_SERVICE_ALREADY_USED_PORT" : "Port {0} is already being used. Choose a different port and try again.\n{1}",
"SUITECLOUD_AUTH_PROXY_SERVICE_INTERNAL_PROXY_SERVER_ERROR" : "There was an internal problem in the SuiteCloud client server while listening on the port {0}.\n{1}",

"UNIT_TEST_TEST_FAILED": "The tests failed.",
"UNIT_TEST_TEST_FAILURES_PRESENT": "There are some Test failures. The deployment will not continue.",
Expand Down
50 changes: 37 additions & 13 deletions packages/node-cli/src/services/SuiteCloudAuthProxyService.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ const EventEmitter = require('events');
/** Events */
const EVENTS = {
SERVER_ERROR: 'serverError',
SERVER_ERROR_ON_REFRESH: 'serverErrorOnRefresh',
AUTH_REFRESH_MANUAL_EVENT: 'authRefreshManual',
PROXY_ERROR: 'proxyError'
};

/** Authentication methods */
Expand All @@ -28,7 +30,7 @@ const {
/** Message literal service method */
const NodeTranslationService = require('./NodeTranslationService');
const {
DEV_ASSIST_PROXY_SERVICE,
SUITECLOUD_AUTH_PROXY_SERVICE,
} = require('./TranslationKeys');

const MAX_RETRY_ATTEMPTS = 1;
Expand Down Expand Up @@ -84,7 +86,7 @@ class SuiteCloudAuthProxyService extends EventEmitter {

//Save body
const bodyChunks = [];
request.on('data', function(chunk) {
request.on('data', function (chunk) {
bodyChunks.push(chunk);
});

Expand All @@ -100,6 +102,13 @@ class SuiteCloudAuthProxyService extends EventEmitter {
const localURL = `http://${LOCAL_HOSTNAME}:${proxyPort}`;
console.log(`SuiteCloud Proxy server listening on ${localURL}`);
});

this._localProxy.on('error', (error) => {
const errorMessage = (error.code === 'EADDRINUSE') ?
NodeTranslationService.getMessage(SUITECLOUD_AUTH_PROXY_SERVICE.ALREADY_USED_PORT, proxyPort, error.message ?? '')
: NodeTranslationService.getMessage(SUITECLOUD_AUTH_PROXY_SERVICE.INTERNAL_PROXY_SERVER_ERROR, proxyPort, error.message ?? '');
this._handleListeningErrors(errorMessage, EVENTS.PROXY_ERROR);
});
}

/**
Expand All @@ -124,6 +133,11 @@ class SuiteCloudAuthProxyService extends EventEmitter {
console.log('access token refreshed');
}

_handleListeningErrors(errorMsg, event) {
console.error(errorMsg);
this.emit(event, this._buildEmitObject(errorMsg));
}

/**
* It validates the input parameters
* @param authId
Expand All @@ -132,15 +146,15 @@ class SuiteCloudAuthProxyService extends EventEmitter {
*/
_evalInputParameters(authId, proxyPort) {
if (!authId) {
throw NodeTranslationService.getMessage(DEV_ASSIST_PROXY_SERVICE.MISSING_AUTH_ID);
throw NodeTranslationService.getMessage(SUITECLOUD_AUTH_PROXY_SERVICE.MISSING_AUTH_ID);
}

if (!proxyPort) {
throw NodeTranslationService.getMessage(DEV_ASSIST_PROXY_SERVICE.MISSING_PORT);
throw NodeTranslationService.getMessage(SUITECLOUD_AUTH_PROXY_SERVICE.MISSING_PORT);
}

if (isNaN(proxyPort)) {
throw NodeTranslationService.getMessage(DEV_ASSIST_PROXY_SERVICE.PORT_MUST_BE_NUMBER);
throw NodeTranslationService.getMessage(SUITECLOUD_AUTH_PROXY_SERVICE.PORT_MUST_BE_NUMBER);
}
}

Expand All @@ -157,7 +171,7 @@ class SuiteCloudAuthProxyService extends EventEmitter {
}

if (!authIDActionResult.data.hasOwnProperty(this._authId)) {
throw NodeTranslationService.getMessage(DEV_ASSIST_PROXY_SERVICE.NOT_EXISTING_AUTH_ID, this._authId);
throw NodeTranslationService.getMessage(SUITECLOUD_AUTH_PROXY_SERVICE.NOT_EXISTING_AUTH_ID, this._authId);
}
return {
accessToken: authIDActionResult.data[this._authId].token.accessToken,
Expand Down Expand Up @@ -205,12 +219,10 @@ class SuiteCloudAuthProxyService extends EventEmitter {
newProxyRequest.write(body);
newProxyRequest.end();
} else {
const emitObject = { message: refreshOperationResult.errorMessage, authId: this._authId };
this.emit(refreshOperationResult.emitEventName, emitObject);
this.emit(refreshOperationResult.emitEventName, this._buildEmitObject(refreshOperationResult.errorMessage));
//Message shown to cline
this._writeResponseMessage(response, refreshOperationResult.responseStatusCode, refreshOperationResult.errorMessage);
proxyResponse.pipe(response, { end: true });

}
} else {
response.writeHead(proxyResponse.statusCode || HTTP_RESPONSE_CODE.INTERNAL_SERVER_ERROR, proxyResponse.headers);
Expand All @@ -222,6 +234,7 @@ class SuiteCloudAuthProxyService extends EventEmitter {
proxyRequest.on('error', (err) => {
console.error('Proxy request error:', err);
response.writeHead(HTTP_RESPONSE_CODE.INTERNAL_SERVER_ERROR);
this.emit(EVENTS.SERVER_ERROR, this._buildEmitObject(err.message));
//TODO Review this message and see confluence error pages and review with the tech writers
response.end('SuiteCloud Proxy error: ' + err.message);
});
Expand Down Expand Up @@ -249,7 +262,7 @@ class SuiteCloudAuthProxyService extends EventEmitter {
if (!inspectAuthOperationResult.isSuccess()) {
const errorMsg = this._cleanText(inspectAuthOperationResult.errorMessages.join('. '));

refreshInfo.emitEventName = EVENTS.SERVER_ERROR;
refreshInfo.emitEventName = EVENTS.SERVER_ERROR_ON_REFRESH;
refreshInfo.errorMessage = errorMsg;
refreshInfo.responseStatusCode = HTTP_RESPONSE_CODE.FORBIDDEN;

Expand All @@ -259,7 +272,7 @@ class SuiteCloudAuthProxyService extends EventEmitter {
//Needs manual reauthorization
const inspectAuthData = inspectAuthOperationResult.data;
if (inspectAuthData[AUTHORIZATION_PROPERTIES_KEYS.NEEDS_REAUTHORIZATION]) {
const errorMsg = NodeTranslationService.getMessage(DEV_ASSIST_PROXY_SERVICE.NEED_TO_REAUTHENTICATE);
const errorMsg = NodeTranslationService.getMessage(SUITECLOUD_AUTH_PROXY_SERVICE.NEED_TO_REAUTHENTICATE);

refreshInfo.emitEventName = EVENTS.AUTH_REFRESH_MANUAL_EVENT;
refreshInfo.errorMessage = errorMsg;
Expand Down Expand Up @@ -289,14 +302,25 @@ class SuiteCloudAuthProxyService extends EventEmitter {
}
}

/**
* This method is created in order to have centralized the structure of the
* emit object in case it should be changed into the future
* @param errorMsg
* @returns {{message, authId}}
* @private
*/
_buildEmitObject(errorMsg) {
return { message: errorMsg, authId: this._authId };
}

/**
* Method to clear output messages.
* The reason for this is the output do not show properly \n and \r
* So they are replaced by . and made some extra adjustments.
* @param input
* @returns {*}
*/
_cleanText(input){
_cleanText(input) {
let result = input.replace(/\r/g, ''); // Remove \r
result = result.replace(/\n/g, '. '); // Replace \n with ". "
result = result.replace(/,\./g, '.'); // Replace ",." with "."
Expand Down Expand Up @@ -336,4 +360,4 @@ class SuiteCloudAuthProxyService extends EventEmitter {

}

module.exports = { SuiteCloudAuthProxyService: SuiteCloudAuthProxyService, EVENTS };
module.exports = { SuiteCloudAuthProxyService, EVENTS };
14 changes: 8 additions & 6 deletions packages/node-cli/src/services/TranslationKeys.js
Original file line number Diff line number Diff line change
Expand Up @@ -444,12 +444,14 @@ module.exports = {
FILE_NOT_AVAILABLE_ERROR: 'SDK_DOWNLOAD_SERVICE_FILE_NOT_AVAILABLE_ERROR',
WRONG_DOWNLOAD_URL_PROTOCOL: 'SDK_DOWNLOAD_SERVICE_WRONG_DOWNLOAD_URL_PROTOCOL',
},
DEV_ASSIST_PROXY_SERVICE: {
MISSING_AUTH_ID: 'DEV_ASSIST_PROXY_SERVICE_ERROR_MISSING_AUTH_ID',
MISSING_PORT: 'DEV_ASSIST_PROXY_SERVICE_ERROR_MISSING_PORT',
PORT_MUST_BE_NUMBER: 'DEV_ASSIST_PROXY_SERVICE_ERROR_PORT_MUST_BE_NUMBER',
NOT_EXISTING_AUTH_ID: 'DEV_ASSIST_PROXY_SERVICE_NOT_EXISTING_AUTH_ID',
NEED_TO_REAUTHENTICATE: 'DEV_ASSIST_PROXY_SERVICE_NEED_TO_REAUTHENTICATE',
SUITECLOUD_AUTH_PROXY_SERVICE: {
MISSING_AUTH_ID: 'SUITECLOUD_AUTH_PROXY_SERVICE_ERROR_MISSING_AUTH_ID',
MISSING_PORT: 'SUITECLOUD_AUTH_PROXY_SERVICE_ERROR_MISSING_PORT',
PORT_MUST_BE_NUMBER: 'SUITECLOUD_AUTH_PROXY_SERVICE_ERROR_PORT_MUST_BE_NUMBER',
NOT_EXISTING_AUTH_ID: 'SUITECLOUD_AUTH_PROXY_SERVICE_NOT_EXISTING_AUTH_ID',
NEED_TO_REAUTHENTICATE: 'SUITECLOUD_AUTH_PROXY_SERVICE_NEED_TO_REAUTHENTICATE',
ALREADY_USED_PORT: 'SUITECLOUD_AUTH_PROXY_SERVICE_ALREADY_USED_PORT',
INTERNAL_PROXY_SERVER_ERROR: 'SUITECLOUD_AUTH_PROXY_SERVICE_INTERNAL_PROXY_SERVER_ERROR',
},
UNIT_TEST: {
TEST_FAILED: 'UNIT_TEST_TEST_FAILED',
Expand Down
3 changes: 3 additions & 0 deletions packages/vscode-extension/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
"DEPLOY_QUESTIONS_CHOICES_ACCOUNT_SPECIFIC_VALUES_CANCEL_PROCESS": "Cancel the deployment process",
"DEPLOY_QUESTIONS_CHOICES_ACCOUNT_SPECIFIC_VALUES_DISPLAY_WARNING": "Display a warning and continue the deployment process",

"DEVASSIST_SERVICE_OUTPUT_PROXY_ERROR": "There was a problem while running SuiteCloud Developer Assistant service.\n{0}",
"DEVASSIST_SERVICE_OUTPUT_SERVER_ERROR": "There was a server error while running SuiteCloud Developer Assistant service.\n{0}",
"DEVASSIST_SERVICE_OUTPUT_SERVER_ERROR_ON_REFRESH": "There was a problem refreshing credentials.\n{0}",
"DEVASSIST_SERVICE_IS_DISABLED_NOTIFICATION": "SuiteCloud Developer Assistant service has been disabled.",
"DEVASSIST_SERVICE_IS_DISABLED_OUTPUT": "SuiteCloud Developer Assistant service has been disabled.",
"DEVASSIST_SERVICE_IS_RUNNING_NOTIFICATION": "SuiteCloud Developer Assistant service is running. Use Cline Base URL to: {0}",
Expand Down
12 changes: 8 additions & 4 deletions packages/vscode-extension/src/service/TranslationKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,16 @@ export const DEPLOY = {
};

export const DEVASSIST_SERVICE = {
EMIT_ERROR: {
OUTPUT: {
PROXY_ERROR: 'DEVASSIST_SERVICE_OUTPUT_PROXY_ERROR',
SERVER_ERROR: 'DEVASSIST_SERVICE_OUTPUT_SERVER_ERROR',
SERVER_ERROR_ON_REFRESH: 'DEVASSIST_SERVICE_OUTPUT_SERVER_ERROR_ON_REFRESH',
}
},
IS_DISABLED: {
NOTIFICATION: 'DEVASSIST_SERVICE_IS_DISABLED_NOTIFICATION',
OUTPUT: 'DEVASSIST_SERVICE_IS_DISABLED_OUTPUT',
OUTPUT: 'DEVASSIST_SERVICE_IS_DISABLED_OUTPUT',
},
IS_RUNNING: {
NOTIFICATION: 'DEVASSIST_SERVICE_IS_RUNNING_NOTIFICATION',
Expand All @@ -113,9 +120,6 @@ export const DEVASSIST_SERVICE = {
OUTPUT: 'DEVASSIST_SERVICE_IS_STOPPED_OUTPUT',
STATUSBAR: 'DEVASSIST_SERVICE_IS_STOPPED_STATUSBAR'
},
SERVER_ERROR: {
OUTPUT: 'DEVASSIST_SERVICE_SERVER_ERROR_OUTPUT'
},
STARTUP: {
BUTTON: {
DONT_SHOW_AGAIN: 'DEVASSIST_SERVICE_STARTUP_BUTTON_DONT_SHOW_AGAIN',
Expand Down
44 changes: 38 additions & 6 deletions packages/vscode-extension/src/startup/DevAssistConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ const devAssistConfigStatus: { current: devAssistConfig, previous: devAssistConf

const PROXY_SERVICE_EVENTS = {
REAUTHORIZE: 'authRefreshManual',
SERVER_ERROR: 'serverError'
SERVER_ERROR: 'serverError',
PROXY_ERROR: 'proxyError',
SERVER_ERROR_ON_REFRESH: 'serverErrorOnRefresh'
}

const executionEnvironmentContext = new ExecutionEnvironmentContext({
Expand Down Expand Up @@ -122,14 +124,25 @@ const initializeDevAssistService = (devAssistStatusBar: vscode.StatusBarItem) =>
}
});

// adding listener to forward ServerError from SutieCloudAuthProxy to vscode suitecloud output
// adding listener to forward ServerError from SuiteCloudAuthProxy to vscode suitecloud output
devAssistProxyService.on(PROXY_SERVICE_EVENTS.SERVER_ERROR, (emitParams: { authId: string, message: string }) => {
// just forwarding info into suitecloud output for now
vsLogger.printTimestamp();
vsLogger.error(translationService.getMessage(DEVASSIST_SERVICE.SERVER_ERROR.OUTPUT, emitParams.message));
// add line separator
const errorMessage = translationService.getMessage(DEVASSIST_SERVICE.EMIT_ERROR.OUTPUT.SERVER_ERROR, emitParams.message);
showDevAssistEmitProblemNotification(PROXY_SERVICE_EVENTS.SERVER_ERROR, errorMessage, devAssistStatusBar);
vsLogger.error('');
});

devAssistProxyService.on(PROXY_SERVICE_EVENTS.PROXY_ERROR, (emitParams: { authId: string, message: string }) => {
const errorMessage = translationService.getMessage(DEVASSIST_SERVICE.EMIT_ERROR.OUTPUT.PROXY_ERROR, emitParams.message);
showDevAssistEmitProblemNotification(PROXY_SERVICE_EVENTS.PROXY_ERROR, errorMessage, devAssistStatusBar);
vsLogger.error('');
});

devAssistProxyService.on(PROXY_SERVICE_EVENTS.SERVER_ERROR_ON_REFRESH, (emitParams: { authId: string, message: string }) => {
const errorMessage = translationService.getMessage(DEVASSIST_SERVICE.EMIT_ERROR.OUTPUT.SERVER_ERROR_ON_REFRESH, emitParams.message);
showDevAssistEmitProblemNotification(PROXY_SERVICE_EVENTS.SERVER_ERROR_ON_REFRESH, errorMessage, devAssistStatusBar);
vsLogger.error('');
});

};

const startDevAssistService = async (devAssistAuthID: string, localPort: number, devAssistStatusBar: vscode.StatusBarItem) => {
Expand Down Expand Up @@ -198,6 +211,25 @@ const showStartDevAssistProblemNotification = (errorStage: string, error: string
vsNotificationService.showCommandErrorWithSpecificButtonsAndActions(errorMessage, buttonsAndActions);
}

const showDevAssistEmitProblemNotification = (errorStage: string, emitError: string, devAssistStatusBar: vscode.StatusBarItem) => {
// console.log(`There was a problem when starting DevAssist service. (${errorStage})\n${error}`)
setErrorDevAssistStausBarMessage(devAssistStatusBar)
vsLogger.printTimestamp();
vsLogger.error(emitError);
const errorMessage = translationService.getMessage(DEVASSIST_SERVICE.IS_STOPPED.NOTIFICATION);
const buttonsAndActions: { buttonMessage: string, buttonAction: () => void }[] = [
{
buttonMessage: translationService.getMessage(DEVASSIST_SERVICE.IS_STOPPED.NOTIFICATION_BUTTON),
buttonAction: () => {
// show suitecloud output and devassist settings
output.show()
openDevAssistSettings();
},
},
];
vsNotificationService.showCommandErrorWithSpecificButtonsAndActions(errorMessage, buttonsAndActions);
}

const openDevAssistSettings = () => {
vscode.commands.executeCommand(
'workbench.action.openWorkspaceSettings',
Expand Down