@dataroadinc/setup-auth
Version:
CLI tool and programmatic API for automated OAuth setup across cloud platforms
87 lines (86 loc) • 3.56 kB
JavaScript
import { SetupAuthError } from "../../utils/error.js";
import axios from "axios";
import { gcpGetAuthorizationHeader } from "./auth.js";
export async function gcpCallAPI(url, method, data) {
try {
const response = await axios({
url,
method,
data,
headers: {
Authorization: await gcpGetAuthorizationHeader(),
"Content-Type": "application/json",
},
});
return response.data;
}
catch (error) {
if (axios.isAxiosError(error) && error.response) {
const statusCode = error.response.status;
const statusText = error.response.statusText;
let errorDetail = "";
if (statusCode === 404) {
errorDetail = `Resource not found at ${url}`;
}
else if (error.response.data) {
if (typeof error.response.data === "string") {
if (error.response.data.includes("<!DOCTYPE html>")) {
errorDetail = "HTML error page returned";
}
else {
errorDetail = error.response.data;
}
}
else if (typeof error.response.data === "object") {
const errorData = error.response.data;
if (errorData.error) {
if (typeof errorData.error === "string") {
errorDetail = errorData.error;
}
else {
errorDetail = JSON.stringify({
message: errorData.error.message,
status: errorData.error.status,
code: errorData.error.code,
details: errorData.error.details,
}, null, 2);
}
}
else {
errorDetail = JSON.stringify(errorData, null, 2);
}
}
}
const responseData = error.response?.data;
const isAlreadyExists = statusCode === 409 && responseData?.error?.status === "ALREADY_EXISTS";
if (!isAlreadyExists) {
console.error(`GCP API Error Details:\nURL: ${url}\nMethod: ${method}\nStatus: ${statusCode} ${statusText}\nError: ${errorDetail}\n${data ? `Request Data: ${JSON.stringify(data, null, 2)}` : ""}`);
}
throw new SetupAuthError(`GCP API error: ${statusCode} ${statusText} - ${errorDetail}`, { cause: error });
}
throw error;
}
}
export async function retryWithBackoff(fn, maxRetries = 3, initialDelay = 1000, operation = "operation") {
let retries = 0;
let lastError;
while (retries <= maxRetries) {
try {
return await fn();
}
catch (error) {
lastError = error;
if (!error?.message?.includes("concurrent policy changes")) {
throw error;
}
if (retries === maxRetries) {
break;
}
retries++;
const delay = initialDelay * Math.pow(2, retries - 1);
console.log(`Retrying ${operation} after ${delay}ms due to concurrent policy change (attempt ${retries}/${maxRetries})...`);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
throw lastError;
}