Skip to content

Commit

Permalink
Adding error handling for 400 and 500 api errors. Added Artifactory R…
Browse files Browse the repository at this point in the history
…epository Name field to avoid calling repos that the pipeline doesn't have acces too.
  • Loading branch information
Robthreefold committed Jun 13, 2024
1 parent 583cb92 commit 61661d0
Show file tree
Hide file tree
Showing 2,153 changed files with 380,217 additions and 91 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
node_modules
.dccache
*.vsix
55 changes: 48 additions & 7 deletions task/artifactory-api-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,19 +73,38 @@ function setProperties(properties) {
const queryParams = {
"properties": [prop] + '=' + properties[prop], // Assuming 'prop' and 'properties' are defined elsewhere
};
axios_1.default.put(artifactUrl, null, {
setTimeout(() => axios_1.default.put(artifactUrl, null, {
params: queryParams,
headers: headers,
})
.then(response => {
console.log(`Successfully set property '${prop}' on Artifact ${artifactUrlShort}`);
})
.catch(error => {
//test
console.log('Error while attempting to add property to Artifact:' + error);
// Handle errors here
process.exit(1); // Exiting with a non-zero code indicating an error
});
for (let errorStatus of error.response.data.errors) {
switch (errorStatus.status) {
case 400:
console.log(`Invalid request parameters (headers / body). See headers here: ${headers} '\n Throwing failing code of 1`);
process.exit(1);
case 401:
console.log(`Endpoint requires authentication, please specify credentials. Message from endpoint is: ${errorStatus.message} ${errorStatus.status} \n Throwing failing code of 1`);
process.exit(1);
case 403:
console.log(`Endpoint permission requirements are not met. Message from endpoint is: Message from endpoint is: ${errorStatus.message} ${errorStatus.status} Please check that account has permission to ${prop} property on Artifact ${artifactUrlShort}.`);
console.log(`Artifact URL endpoint that failed ${artifactUrl}`);
process.exit(1);
case 500:
console.log(`Server error! Unexpected error during request handling, check distribution logs. Message from endpoint is: ${errorStatus.message} ${errorStatus.status} \n Throwing failing code of 1`);
process.exit(1);
default:
console.log(`Endpoint failed with the following error: ${error.message} \n Throwing failing code of 1`);
process.exit(1);
}
}
// process.exit(1); // Exiting with a non-zero code indicating an error
}), 1000);
});
}
}
Expand All @@ -94,7 +113,8 @@ function setProperties(properties) {
const buildNumber = tl.getInput('BuildNumber', true);
const projectName = tl.getInput('ProjectKey', true);
const BuildStatus = tl.getInput('BuildStatus', false);
const searchBody = Object.assign({ "buildName": buildName, "buildNumber": buildNumber, "project": projectName }, (BuildStatus !== null && { myProperty: BuildStatus }));
const repos = tl.getInput('ArtifactoryRepositoryName', false);
const searchBody = Object.assign(Object.assign({ "buildName": buildName, "buildNumber": buildNumber, "project": projectName }, (repos !== undefined && { repos: [repos] })), (BuildStatus !== null && { buildStatus: BuildStatus }));
const searchUrl = `${baseUrl}/api/search/buildArtifacts`;
axios_1.default.post(searchUrl, JSON.stringify(searchBody), {
headers: headers,
Expand Down Expand Up @@ -122,15 +142,36 @@ function setProperties(properties) {
// Adding a delay between each API call
})
.catch(error => {
console.log('Error while attempting to add property to Artifact: ' + error);
console.log('Error while attempting to add property to Artifact:' + error);
// Handle errors here
process.exit(1); // Exiting with a non-zero code indicating an error
for (let errorStatus of error.response.data.errors) {
switch (errorStatus.status) {
case 400:
console.log(`Invalid request parameters (headers / body). See headers here: ${headers} '\n Throwing failing code of 1`);
process.exit(1);
case 401:
console.log(`Endpoint requires authentication, please specify credentials. Message from endpoint is: ${errorStatus.message} ${errorStatus.status} \n Throwing failing code of 1`);
process.exit(1);
case 403:
console.log(`Endpoint permission requirements are not met. Message from endpoint is: Message from endpoint is: ${errorStatus.message} ${errorStatus.status} Please check that account has permission to ${prop} property on Artifact ${artifactUrlShort}.`);
console.log(`Here is the artifact URL ${artifactUrl}`);
process.exit(1);
case 500:
console.log(`Server error! Unexpected error during request handling, check distribution logs. Message from endpoint is: ${errorStatus.message} ${errorStatus.status} \n Throwing failing code of 1`);
process.exit(1);
default:
console.log(`Endpoint failed with the following error: ${error.message} \n Throwing failing code of 1`);
process.exit(1);
}
}
// process.exit(1); // Exiting with a non-zero code indicating an error
}), 1000);
});
}
})
.catch((error) => {
console.error('Error from Artifactory search builds API:', error.response ? error.response.data : error.message);
console.log(`Artifactory search builds body: \n ${JSON.stringify(searchBody)}`);
process.exit(1);
});
}
Expand Down
183 changes: 114 additions & 69 deletions task/artifactory-api-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { json } from 'stream/consumers';
axiosRetry(axios, {
retries: 10, // Number of retries
retryDelay: axiosRetry.exponentialDelay, // Retry delay strategy
onRetry: (retryCount, error, Config)=>{console.log("Axios request failed with " + error + " retrying now..")}
onRetry: (retryCount, error, Config) => { console.log("Axios request failed with " + error + " retrying now..") }
});

export function setProperties(properties: any): void {
Expand Down Expand Up @@ -37,90 +37,135 @@ export function setProperties(properties: any): void {
};
//Retrieve artifact URLs
let artifactUrls: any = []
if (inputType == "urllist"){
if (inputType == "urllist") {
const delimiter: any = tl.getInput('delimiter', false) || ','
artifactUrls = tl.getInput('artifactUrls', true)?.split(delimiter);

//add properties to each artifact
for (let artifactUrlShort of artifactUrls) {
artifactUrlShort = Utils.encodeUrl(artifactUrlShort);
const artifactUrl = `${baseUrl}/api/storage/${artifactUrlShort}`; // Construct the complete URL
Object.keys(properties).forEach((prop) => {
const queryParams = {
//add properties to each artifact
for (let artifactUrlShort of artifactUrls) {
artifactUrlShort = Utils.encodeUrl(artifactUrlShort);
const artifactUrl = `${baseUrl}/api/storage/${artifactUrlShort}`; // Construct the complete URL

Object.keys(properties).forEach((prop) => {
const queryParams = {
"properties": [prop] + '=' + properties[prop], // Assuming 'prop' and 'properties' are defined elsewhere
};
axios.put(artifactUrl, null, {
params: queryParams,
headers: headers,
})
.then(response => {
console.log(`Successfully set property '${prop}' on Artifact ${artifactUrlShort}`)
})
.catch(error => {
//test
console.log('Error while attempting to add property to Artifact:' + error);
// Handle errors here
process.exit(1); // Exiting with a non-zero code indicating an error
};
setTimeout(() =>
axios.put(artifactUrl, null, {
params: queryParams,
headers: headers,
})
.then(response => {
console.log(`Successfully set property '${prop}' on Artifact ${artifactUrlShort}`)
})
.catch(error => {
console.log('Error while attempting to add property to Artifact:' + error);
// Handle errors here
for (let errorStatus of error.response.data.errors) {
switch (errorStatus.status) {
case 400:
console.log(`Invalid request parameters (headers / body). See headers here: ${headers} '\n Throwing failing code of 1`);
process.exit(1)
case 401:
console.log(`Endpoint requires authentication, please specify credentials. Message from endpoint is: ${errorStatus.message} ${errorStatus.status} \n Throwing failing code of 1`);
process.exit(1)
case 403:
console.log(`Endpoint permission requirements are not met. Message from endpoint is: Message from endpoint is: ${errorStatus.message} ${errorStatus.status} Please check that account has permission to ${prop} property on Artifact ${artifactUrlShort}.`);
console.log(`Artifact URL endpoint that failed ${artifactUrl}`);
process.exit(1)
case 500:
console.log(`Server error! Unexpected error during request handling, check distribution logs. Message from endpoint is: ${errorStatus.message} ${errorStatus.status} \n Throwing failing code of 1`);
process.exit(1)
default:
console.log(`Endpoint failed with the following error: ${error.message} \n Throwing failing code of 1`);
process.exit(1)
}
}
// process.exit(1); // Exiting with a non-zero code indicating an error
})
, 1000)
});
});
}
}else if (inputType == "build"){
}
} else if (inputType == "build") {

const buildName = tl.getInput('BuildName', true)
const buildNumber = tl.getInput('BuildNumber', true)
const projectName = tl.getInput('ProjectKey', true)
const BuildStatus = tl.getInput('BuildStatus', false)
const repos = tl.getInput('ArtifactoryRepositoryName', false)

const searchBody = {
"buildName": buildName,
"buildNumber": buildNumber,
"project" : projectName,
...(BuildStatus !== null && { myProperty: BuildStatus }),
"project": projectName,
...(repos !== undefined && { repos: [repos] }),
...(BuildStatus !== null && { buildStatus: BuildStatus }),
}

const searchUrl = `${baseUrl}/api/search/buildArtifacts`
axios.post(searchUrl, JSON.stringify(searchBody), {
headers: headers,
})
.then((response) => {
console.log("Data received from build search API: " + JSON.stringify(response.data))
artifactUrls = response.data.results.map((obj: any) => {
const { downloadUri } = obj;
const trimmedUrl = downloadUri.replace(`${baseUrl}/`, "");
return trimmedUrl;
}
);
const searchUrl = `${baseUrl}/api/search/buildArtifacts`
axios.post(searchUrl, JSON.stringify(searchBody), {
headers: headers,
})
.then((response) => {
console.log("Data received from build search API: " + JSON.stringify(response.data))
artifactUrls = response.data.results.map((obj: any) => {
const { downloadUri } = obj;
const trimmedUrl = downloadUri.replace(`${baseUrl}/`, "");
return trimmedUrl;
}
);

for (let artifactUrlShort of artifactUrls) {
artifactUrlShort = Utils.encodeUrl(artifactUrlShort);
const artifactUrl = `${baseUrl}/api/storage/${artifactUrlShort}`; // Construct the complete URL

Object.keys(properties).forEach((prop) => {
const queryParams = {
"properties": [prop] + '=' + properties[prop], // Assuming 'prop' and 'properties' are defined elsewhere
};
setTimeout(()=>
axios.put(artifactUrl, null, {
params: queryParams,
headers: headers,
})
.then(response => {
console.log(`Successfully set property '${prop}' on Artifact ${artifactUrlShort}`)
for (let artifactUrlShort of artifactUrls) {
artifactUrlShort = Utils.encodeUrl(artifactUrlShort);
const artifactUrl = `${baseUrl}/api/storage/${artifactUrlShort}`; // Construct the complete URL

// Adding a delay between each API call
})
.catch(error => {
console.log('Error while attempting to add property to Artifact: ' + error);
// Handle errors here
process.exit(1); // Exiting with a non-zero code indicating an error
Object.keys(properties).forEach((prop) => {
const queryParams = {
"properties": [prop] + '=' + properties[prop], // Assuming 'prop' and 'properties' are defined elsewhere
};
setTimeout(() =>
axios.put(artifactUrl, null, {
params: queryParams,
headers: headers,
})
.then(response => {
console.log(`Successfully set property '${prop}' on Artifact ${artifactUrlShort}`)

// Adding a delay between each API call
})
.catch(error => {
console.log('Error while attempting to add property to Artifact:' + error);
// Handle errors here
for (let errorStatus of error.response.data.errors) {
switch (errorStatus.status) {
case 400:
console.log(`Invalid request parameters (headers / body). See headers here: ${headers} '\n Throwing failing code of 1`);
process.exit(1)
case 401:
console.log(`Endpoint requires authentication, please specify credentials. Message from endpoint is: ${errorStatus.message} ${errorStatus.status} \n Throwing failing code of 1`);
process.exit(1)
case 403:
console.log(`Endpoint permission requirements are not met. Message from endpoint is: Message from endpoint is: ${errorStatus.message} ${errorStatus.status} Please check that account has permission to ${prop} property on Artifact ${artifactUrlShort}.`);
console.log(`Here is the artifact URL ${artifactUrl}`);
process.exit(1)
case 500:
console.log(`Server error! Unexpected error during request handling, check distribution logs. Message from endpoint is: ${errorStatus.message} ${errorStatus.status} \n Throwing failing code of 1`);
process.exit(1)
default:
console.log(`Endpoint failed with the following error: ${error.message} \n Throwing failing code of 1`);
process.exit(1)
}
}
// process.exit(1); // Exiting with a non-zero code indicating an error
})
, 1000)
});
}
})
, 1000)
});
.catch((error) => {
console.error('Error from Artifactory search builds API:', error.response ? error.response.data : error.message);
console.log(`Artifactory search builds body: \n ${JSON.stringify(searchBody)}`)
process.exit(1)
});
}
})
.catch((error) => {
console.error('Error from Artifactory search builds API:', error.response ? error.response.data : error.message);
process.exit(1)
});
}
}
}
1 change: 1 addition & 0 deletions task/node_modules/.bin/bunyan

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions task/node_modules/.bin/mkdirp

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions task/node_modules/.bin/ncp

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions task/node_modules/.bin/resolve

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions task/node_modules/.bin/rimraf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions task/node_modules/.bin/semver

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions task/node_modules/.bin/shjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions task/node_modules/.bin/uuid

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 61661d0

Please sign in to comment.