@cloud-copilot/iam-collect
Version:
Collect IAM information from AWS Accounts
112 lines • 3.59 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.runAndCatch404 = runAndCatch404;
exports.runAndCatchAccessDenied = runAndCatchAccessDenied;
exports.runAndCatchAccessDeniedWithLog = runAndCatchAccessDeniedWithLog;
exports.runAndCatchError = runAndCatchError;
exports.withDnsRetry = withDnsRetry;
const log_1 = require("@cloud-copilot/log");
/**
*
* @param operation The operation to run.
* @returns If successful, returns the result of operation. If operation returns a 404, returns undefined.
* @throws If operation returns a non 404 error, rethrows that error.
*/
async function runAndCatch404(operation) {
try {
const result = await operation();
return result;
}
catch (e) {
if (e['$metadata']?.httpStatusCode == 404) {
return undefined;
}
throw e;
}
}
/**
*
* @param operation The operation to run.
* @returns If successful, returns the result of operation. If operation returns a 404, returns undefined.
* @throws If operation returns a non 400 error, rethrows that error.
*/
async function runAndCatchAccessDenied(operation, onError) {
try {
const result = await operation();
return result;
}
catch (e) {
const errorName = e.name;
if (errorName == 'AccessDeniedException' ||
errorName == 'AccessDenied' ||
errorName == 'AuthorizationErrorException') {
if (onError) {
return onError(e);
}
return undefined;
}
throw e;
}
}
async function runAndCatchAccessDeniedWithLog(arn, awsService, resourceType, field, operation) {
return runAndCatchAccessDenied(operation, async (error) => {
log_1.log.warn(`Access denied for ${field} in ${arn}`, error, {
accessDenied: true,
arn,
field,
resourceType,
awsService
});
return undefined;
});
}
/**
* Run an operation and catch a specific error by name. Return undefined if the error matches, otherwise rethrow the error.
*
* @param errorName the name of the error to catch
* @param operation the operation to run
* @returns If successful, returns the result of operation. If operation throws an error with the specified name, returns undefined.
* @throws If operation throws an error with a different name, rethrows that error.
*/
async function runAndCatchError(errorName, operation, onError) {
try {
const result = await operation();
return result;
}
catch (e) {
if (e.name == errorName) {
if (onError) {
return onError(e);
}
return undefined;
}
throw e;
}
}
const DNS_RETRY_DELAY = 1_500;
/**
* Retry a function that may fail due to DNS resolution issues.
*
* @param fn the function to retry
* @param tries the number of times to retry the function
* @returns the result of the function if successful, otherwise throws the last error encountered
*/
async function withDnsRetry(fn, tries = 5) {
let last;
for (let i = 0; i < tries; i++) {
try {
return await fn();
}
catch (e) {
const m = e?.message || '';
if (m.startsWith('getaddrinfo')) {
await new Promise((r) => setTimeout(r, DNS_RETRY_DELAY + Math.random() * DNS_RETRY_DELAY));
last = e;
continue;
}
throw e;
}
}
throw last;
}
//# sourceMappingURL=client-tools.js.map