Skip to content

Commit

Permalink
[JenkinsQueueJobV2] Improved error handling (#13242)
Browse files Browse the repository at this point in the history
* Improved http errors handling

* Reworked logging code

* Replaced console.log with console.error and fixed tests

* Passed Error instance to console.error instead of message field to show more info
  • Loading branch information
egor-bryzgalov authored Jul 13, 2020
1 parent 6ca9a89 commit cbad58b
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 15 deletions.
2 changes: 1 addition & 1 deletion Tasks/JenkinsQueueJobV2/Tests/L0.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ describe('JenkinsQueueJob L0 Suite', function () {
});

it('run JenkinsQueueJob with bogus url with parameters', (done) => {
const tp: string = path.join(__dirname, 'L0BogusUrlNoParameters.js');
const tp: string = path.join(__dirname, 'L0BogusUrlParameters.js');
const tr: ttm.MockTestRunner = new ttm.MockTestRunner(tp);

try {
Expand Down
16 changes: 13 additions & 3 deletions Tasks/JenkinsQueueJobV2/jenkinsqueuejobtask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,19 @@ async function doWork() {
//store the job name in the output variable
tl.setVariable('JENKINS_JOB_ID', rootJob.ExecutableNumber.toString());
} catch (e) {
tl.debug(e.message);
process.stderr.write(e + os.EOL);
tl.setResult(tl.TaskResult.Failed, e.message);
let message: string;
if (e instanceof util.HttpError) {
message = e.message;
console.error(e.fullMessage);
console.error(e.body);
} else if (e instanceof Error) {
message = e.message;
console.error(e);
} else {
message = e;
console.error(e);
}
tl.setResult(tl.TaskResult.Failed, message);
}
}

Expand Down
2 changes: 1 addition & 1 deletion Tasks/JenkinsQueueJobV2/job.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,8 @@ export class Job {
thisJob.stopWork(thisJob.queue.TaskOptions.pollIntervalMillis, thisJob.State);
return;
} else if (httpResponse.statusCode !== 200) {
console.error(`Job was killed because of an response with unexpected status code from Jenkins - ${httpResponse.statusCode}`);
Util.failReturnCode(httpResponse, 'Job progress tracking failed to read job result');
tl.error(`Job was killed because of an response with unexpected status code from Jenkins - ${httpResponse.statusCode}`);
thisJob.stopWork(0, JobState.Killed);
} else {
const parsedBody: {result: string, timestamp: number} = JSON.parse(body);
Expand Down
2 changes: 1 addition & 1 deletion Tasks/JenkinsQueueJobV2/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"demands": [],
"version": {
"Major": 2,
"Minor": 171,
"Minor": 173,
"Patch": 0
},
"groups": [
Expand Down
2 changes: 1 addition & 1 deletion Tasks/JenkinsQueueJobV2/task.loc.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"demands": [],
"version": {
"Major": 2,
"Minor": 171,
"Minor": 173,
"Patch": 0
},
"groups": [
Expand Down
29 changes: 21 additions & 8 deletions Tasks/JenkinsQueueJobV2/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ export function getFullErrorMessage(httpResponse, message: string): string {

export function failReturnCode(httpResponse, message: string): void {
const fullMessage = getFullErrorMessage(httpResponse, message);
tl.debug(message);
tl.error(fullMessage);
process.stderr.write(message + os.EOL);
console.error(fullMessage);
tl.setResult(tl.TaskResult.Failed, message);
}

Expand All @@ -40,6 +38,22 @@ export function fail(message: string): void {
export class FailTaskError extends Error {
}

/**
* @class Represents error based on HttpResponse
* @extends {Error} Error class
*/
export class HttpError extends Error {
public body: string;
public fullMessage: string;

constructor(httpResponse: any, message: string) {
super();
this.fullMessage = getFullErrorMessage(httpResponse, message);
this.message = message;
this.body = httpResponse.body;
}
}

export function convertJobName(jobName: string): string {
return '/job/' + jobName.replace('/', '/job/');
}
Expand Down Expand Up @@ -135,7 +149,7 @@ function createRootJob(queueUri: string, jobQueue: JobQueue, taskOptions: TaskOp
defer.reject(error);
}
} else if (httpResponse.statusCode !== 200) {
defer.reject(getFullErrorMessage(httpResponse, 'Job progress tracking failed to read job queue'));
defer.reject(new HttpError(httpResponse, 'Job progress tracking failed to read job queue'));
} else {
const parsedBody: any = JSON.parse(body);
tl.debug(`parsedBody for: ${queueUri} : ${JSON.stringify(parsedBody)}`);
Expand Down Expand Up @@ -256,14 +270,14 @@ function submitJob(taskOptions: TaskOptions): Q.Promise<string> {
defer.reject(err);
}
} else if (httpResponse.statusCode !== 201) {
defer.reject(getFullErrorMessage(httpResponse, 'Job creation failed.'));
defer.reject(new HttpError(httpResponse, 'Job creation failed.'));
} else {
const queueUri: string = addUrlSegment(httpResponse.headers.location, 'api/json');
defer.resolve(queueUri);
}
}).auth(taskOptions.username, taskOptions.password, true);
} else if (httpResponse.statusCode !== 201) {
defer.reject(getFullErrorMessage(httpResponse, 'Job creation failed.'));
defer.reject(new HttpError(httpResponse, 'Job creation failed.'));
} else {
taskOptions.teamBuildPluginAvailable = true;
const jsonBody: any = JSON.parse(body);
Expand Down Expand Up @@ -293,8 +307,7 @@ function getCrumb(taskOptions: TaskOptions): Q.Promise<string> {
taskOptions.crumb = taskOptions.NO_CRUMB;
defer.resolve(taskOptions.NO_CRUMB);
} else if (httpResponse.statusCode !== 200) {
failReturnCode(httpResponse, 'crumb request failed.');
defer.reject(getFullErrorMessage(httpResponse, 'Crumb request failed.'));
defer.reject(new HttpError(httpResponse, 'Crumb request failed.'));
} else {
taskOptions.crumb = body;
tl.debug('crumb: ' + taskOptions.crumb);
Expand Down

0 comments on commit cbad58b

Please sign in to comment.