Adding Retry Interceptor for Failed Requests and Endpoint Display (#679)
This pull request introduces a new feature that enhances the error handling and user experience in our React application. It implements an interceptor to automatically retry failed requests and provides a clear display of the failing endpoint to the user. Changes Made: Added a new interceptor to the Axios HTTP client in our React application. The interceptor detects failed requests and automatically retries them based on a predefined retry count. When a request fails, the interceptor captures the failing endpoint and stores it. Modified the user interface to display a user-friendly error message indicating the failing endpoint. Enhanced error handling to provide detailed information and better user feedback.
This commit is contained in:
commit
c009602b57
14 changed files with 121 additions and 67 deletions
4
src/frontend/package-lock.json
generated
4
src/frontend/package-lock.json
generated
|
|
@ -29,6 +29,7 @@
|
||||||
"@tabler/icons-react": "^2.18.0",
|
"@tabler/icons-react": "^2.18.0",
|
||||||
"@tailwindcss/forms": "^0.5.3",
|
"@tailwindcss/forms": "^0.5.3",
|
||||||
"@tailwindcss/line-clamp": "^0.4.4",
|
"@tailwindcss/line-clamp": "^0.4.4",
|
||||||
|
"@types/axios": "^0.14.0",
|
||||||
"accordion": "^3.0.2",
|
"accordion": "^3.0.2",
|
||||||
"ace-builds": "^1.16.0",
|
"ace-builds": "^1.16.0",
|
||||||
"add": "^2.0.6",
|
"add": "^2.0.6",
|
||||||
|
|
@ -142,6 +143,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/compat-data": {
|
"node_modules/@babel/compat-data": {
|
||||||
|
"version": "7.22.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.6.tgz",
|
||||||
|
"integrity": "sha512-29tfsWTq2Ftu7MXmimyC0C5FDZv5DYxOZkh3XD3+QW4V/BYuv/LyEsjj3c0hqedEaDt6DBfDvexMKU8YevdqFg==",
|
||||||
"version": "7.22.9",
|
"version": "7.22.9",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
"@tabler/icons-react": "^2.18.0",
|
"@tabler/icons-react": "^2.18.0",
|
||||||
"@tailwindcss/forms": "^0.5.3",
|
"@tailwindcss/forms": "^0.5.3",
|
||||||
"@tailwindcss/line-clamp": "^0.4.4",
|
"@tailwindcss/line-clamp": "^0.4.4",
|
||||||
|
"@types/axios": "^0.14.0",
|
||||||
"accordion": "^3.0.2",
|
"accordion": "^3.0.2",
|
||||||
"ace-builds": "^1.16.0",
|
"ace-builds": "^1.16.0",
|
||||||
"add": "^2.0.6",
|
"add": "^2.0.6",
|
||||||
|
|
|
||||||
|
|
@ -56,4 +56,4 @@ const AccordionContent = React.forwardRef<
|
||||||
));
|
));
|
||||||
AccordionContent.displayName = AccordionPrimitive.Content.displayName;
|
AccordionContent.displayName = AccordionPrimitive.Content.displayName;
|
||||||
|
|
||||||
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };
|
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger };
|
||||||
|
|
|
||||||
|
|
@ -77,9 +77,9 @@ CardFooter.displayName = "CardFooter";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Card,
|
Card,
|
||||||
CardHeader,
|
|
||||||
CardFooter,
|
|
||||||
CardTitle,
|
|
||||||
CardDescription,
|
|
||||||
CardContent,
|
CardContent,
|
||||||
|
CardDescription,
|
||||||
|
CardFooter,
|
||||||
|
CardHeader,
|
||||||
|
CardTitle,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -116,10 +116,10 @@ DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogTrigger,
|
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogHeader,
|
|
||||||
DialogFooter,
|
|
||||||
DialogTitle,
|
|
||||||
DialogDescription,
|
DialogDescription,
|
||||||
|
DialogFooter,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogTrigger,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -182,18 +182,18 @@ DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
DropdownMenuTrigger,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuItem,
|
|
||||||
DropdownMenuCheckboxItem,
|
DropdownMenuCheckboxItem,
|
||||||
DropdownMenuRadioItem,
|
DropdownMenuContent,
|
||||||
|
DropdownMenuGroup,
|
||||||
|
DropdownMenuItem,
|
||||||
DropdownMenuLabel,
|
DropdownMenuLabel,
|
||||||
|
DropdownMenuPortal,
|
||||||
|
DropdownMenuRadioGroup,
|
||||||
|
DropdownMenuRadioItem,
|
||||||
DropdownMenuSeparator,
|
DropdownMenuSeparator,
|
||||||
DropdownMenuShortcut,
|
DropdownMenuShortcut,
|
||||||
DropdownMenuGroup,
|
|
||||||
DropdownMenuPortal,
|
|
||||||
DropdownMenuSub,
|
DropdownMenuSub,
|
||||||
DropdownMenuSubContent,
|
DropdownMenuSubContent,
|
||||||
DropdownMenuSubTrigger,
|
DropdownMenuSubTrigger,
|
||||||
DropdownMenuRadioGroup,
|
DropdownMenuTrigger,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -218,19 +218,19 @@ MenubarShortcut.displayname = "MenubarShortcut";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Menubar,
|
Menubar,
|
||||||
MenubarMenu,
|
|
||||||
MenubarTrigger,
|
|
||||||
MenubarContent,
|
|
||||||
MenubarItem,
|
|
||||||
MenubarSeparator,
|
|
||||||
MenubarLabel,
|
|
||||||
MenubarCheckboxItem,
|
MenubarCheckboxItem,
|
||||||
|
MenubarContent,
|
||||||
|
MenubarGroup,
|
||||||
|
MenubarItem,
|
||||||
|
MenubarLabel,
|
||||||
|
MenubarMenu,
|
||||||
|
MenubarPortal,
|
||||||
MenubarRadioGroup,
|
MenubarRadioGroup,
|
||||||
MenubarRadioItem,
|
MenubarRadioItem,
|
||||||
MenubarPortal,
|
MenubarSeparator,
|
||||||
|
MenubarShortcut,
|
||||||
|
MenubarSub,
|
||||||
MenubarSubContent,
|
MenubarSubContent,
|
||||||
MenubarSubTrigger,
|
MenubarSubTrigger,
|
||||||
MenubarGroup,
|
MenubarTrigger,
|
||||||
MenubarSub,
|
|
||||||
MenubarShortcut,
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -103,11 +103,11 @@ TableCaption.displayName = "TableCaption";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Table,
|
Table,
|
||||||
TableHeader,
|
|
||||||
TableBody,
|
TableBody,
|
||||||
|
TableCaption,
|
||||||
|
TableCell,
|
||||||
TableFooter,
|
TableFooter,
|
||||||
TableHead,
|
TableHead,
|
||||||
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
TableCell,
|
|
||||||
TableCaption,
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -51,4 +51,4 @@ const TabsContent = React.forwardRef<
|
||||||
));
|
));
|
||||||
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
TabsContent.displayName = TabsPrimitive.Content.displayName;
|
||||||
|
|
||||||
export { Tabs, TabsList, TabsTrigger, TabsContent };
|
export { Tabs, TabsContent, TabsList, TabsTrigger };
|
||||||
|
|
|
||||||
|
|
@ -28,4 +28,4 @@ const TooltipContent = React.forwardRef<
|
||||||
));
|
));
|
||||||
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
||||||
|
|
||||||
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
|
export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };
|
||||||
|
|
|
||||||
|
|
@ -71,18 +71,7 @@ export function TypesProvider({ children }: { children: ReactNode }) {
|
||||||
// Clear the interval if successful.
|
// Clear the interval if successful.
|
||||||
clearInterval(intervalId);
|
clearInterval(intervalId);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
retryCount++;
|
console.error("An error has occurred while fetching types.");
|
||||||
// On error, double the delay for the next attempt up to a maximum.
|
|
||||||
delay = Math.min(30000, delay * 2);
|
|
||||||
// Log errors but don't do anything else - the function will try again on the next interval.
|
|
||||||
console.error(error);
|
|
||||||
// Clear the old interval and start a new one with the new delay.
|
|
||||||
if (retryCount <= maxRetryCount) {
|
|
||||||
clearInterval(intervalId);
|
|
||||||
intervalId = setInterval(getTypes, delay);
|
|
||||||
} else {
|
|
||||||
console.error("Max retry attempts reached. Stopping retries.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
58
src/frontend/src/controllers/API/api.tsx
Normal file
58
src/frontend/src/controllers/API/api.tsx
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
import axios, { AxiosError, AxiosInstance } from "axios";
|
||||||
|
import { useContext, useEffect, useRef } from "react";
|
||||||
|
import { alertContext } from "../../contexts/alertContext";
|
||||||
|
|
||||||
|
// Create a new Axios instance
|
||||||
|
const api: AxiosInstance = axios.create({
|
||||||
|
baseURL: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
function ApiInterceptor() {
|
||||||
|
const retryCounts = useRef([]);
|
||||||
|
const { setErrorData } = useContext(alertContext);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const interceptor = api.interceptors.response.use(
|
||||||
|
(response) => response,
|
||||||
|
async (error: AxiosError) => {
|
||||||
|
let retryCount = 0;
|
||||||
|
|
||||||
|
while (retryCount < 4) {
|
||||||
|
await sleep(5000); // Sleep for 5 seconds
|
||||||
|
retryCount++;
|
||||||
|
try {
|
||||||
|
const response = await axios.request(error.config);
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
if (retryCount === 3) {
|
||||||
|
setErrorData({
|
||||||
|
title: "There was an error on web connection, please: ",
|
||||||
|
list: [
|
||||||
|
"Refresh the page",
|
||||||
|
"Use a new flow tab",
|
||||||
|
"Check if the backend is up",
|
||||||
|
"Endpoint: " + error.config.url,
|
||||||
|
],
|
||||||
|
});
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
// Clean up the interceptor when the component unmounts
|
||||||
|
api.interceptors.response.eject(interceptor);
|
||||||
|
};
|
||||||
|
}, [retryCounts]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to sleep for a given duration in milliseconds
|
||||||
|
function sleep(ms) {
|
||||||
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
|
}
|
||||||
|
|
||||||
|
export { ApiInterceptor, api };
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import axios, { AxiosResponse } from "axios";
|
import { AxiosResponse } from "axios";
|
||||||
import { ReactFlowJsonObject } from "reactflow";
|
import { ReactFlowJsonObject } from "reactflow";
|
||||||
|
import { api } from "../../controllers/API/api";
|
||||||
import { APIObjectType, sendAllProps } from "../../types/api/index";
|
import { APIObjectType, sendAllProps } from "../../types/api/index";
|
||||||
import { FlowStyleType, FlowType } from "../../types/flow";
|
import { FlowStyleType, FlowType } from "../../types/flow";
|
||||||
import {
|
import {
|
||||||
|
|
@ -17,16 +18,14 @@ import {
|
||||||
* @returns {Promise<AxiosResponse<APIObjectType>>} A promise that resolves to an AxiosResponse containing all the objects.
|
* @returns {Promise<AxiosResponse<APIObjectType>>} A promise that resolves to an AxiosResponse containing all the objects.
|
||||||
*/
|
*/
|
||||||
export async function getAll(): Promise<AxiosResponse<APIObjectType>> {
|
export async function getAll(): Promise<AxiosResponse<APIObjectType>> {
|
||||||
return await axios.get(`/api/v1/all`);
|
return await api.get(`/api/v1/all`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const GITHUB_API_URL = "https://api.github.com";
|
const GITHUB_API_URL = "https://api.github.com";
|
||||||
|
|
||||||
export async function getRepoStars(owner, repo) {
|
export async function getRepoStars(owner, repo) {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(
|
const response = await api.get(`${GITHUB_API_URL}/repos/${owner}/${repo}`);
|
||||||
`${GITHUB_API_URL}/repos/${owner}/${repo}`
|
|
||||||
);
|
|
||||||
return response.data.stargazers_count;
|
return response.data.stargazers_count;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching repository data:", error);
|
console.error("Error fetching repository data:", error);
|
||||||
|
|
@ -41,13 +40,13 @@ export async function getRepoStars(owner, repo) {
|
||||||
* @returns {AxiosResponse<any>} The API response.
|
* @returns {AxiosResponse<any>} The API response.
|
||||||
*/
|
*/
|
||||||
export async function sendAll(data: sendAllProps) {
|
export async function sendAll(data: sendAllProps) {
|
||||||
return await axios.post(`/api/v1/predict`, data);
|
return await api.post(`/api/v1/predict`, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function postValidateCode(
|
export async function postValidateCode(
|
||||||
code: string
|
code: string
|
||||||
): Promise<AxiosResponse<errorsTypeAPI>> {
|
): Promise<AxiosResponse<errorsTypeAPI>> {
|
||||||
return await axios.post("/api/v1/validate/code", { code });
|
return await api.post("/api/v1/validate/code", { code });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -62,7 +61,7 @@ export async function postValidatePrompt(
|
||||||
template: string,
|
template: string,
|
||||||
frontend_node: APIClassType
|
frontend_node: APIClassType
|
||||||
): Promise<AxiosResponse<PromptTypeAPI>> {
|
): Promise<AxiosResponse<PromptTypeAPI>> {
|
||||||
return await axios.post("/api/v1/validate/prompt", {
|
return await api.post("/api/v1/validate/prompt", {
|
||||||
name: name,
|
name: name,
|
||||||
template: template,
|
template: template,
|
||||||
frontend_node: frontend_node,
|
frontend_node: frontend_node,
|
||||||
|
|
@ -77,14 +76,14 @@ export async function postValidatePrompt(
|
||||||
export async function getExamples(): Promise<FlowType[]> {
|
export async function getExamples(): Promise<FlowType[]> {
|
||||||
const url =
|
const url =
|
||||||
"https://api.github.com/repos/logspace-ai/langflow_examples/contents/examples?ref=main";
|
"https://api.github.com/repos/logspace-ai/langflow_examples/contents/examples?ref=main";
|
||||||
const response = await axios.get(url);
|
const response = await api.get(url);
|
||||||
|
|
||||||
const jsonFiles = response.data.filter((file: any) => {
|
const jsonFiles = response.data.filter((file: any) => {
|
||||||
return file.name.endsWith(".json");
|
return file.name.endsWith(".json");
|
||||||
});
|
});
|
||||||
|
|
||||||
const contentsPromises = jsonFiles.map(async (file: any) => {
|
const contentsPromises = jsonFiles.map(async (file: any) => {
|
||||||
const contentResponse = await axios.get(file.download_url);
|
const contentResponse = await api.get(file.download_url);
|
||||||
return contentResponse.data;
|
return contentResponse.data;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -106,11 +105,12 @@ export async function saveFlowToDatabase(newFlow: {
|
||||||
style?: FlowStyleType;
|
style?: FlowStyleType;
|
||||||
}): Promise<FlowType> {
|
}): Promise<FlowType> {
|
||||||
try {
|
try {
|
||||||
const response = await axios.post("/api/v1/flows/", {
|
const response = await api.post("/api/v1/flows/", {
|
||||||
name: newFlow.name,
|
name: newFlow.name,
|
||||||
data: newFlow.data,
|
data: newFlow.data,
|
||||||
description: newFlow.description,
|
description: newFlow.description,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (response.status !== 201) {
|
if (response.status !== 201) {
|
||||||
throw new Error(`HTTP error! status: ${response.status}`);
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
}
|
}
|
||||||
|
|
@ -131,7 +131,7 @@ export async function updateFlowInDatabase(
|
||||||
updatedFlow: FlowType
|
updatedFlow: FlowType
|
||||||
): Promise<FlowType> {
|
): Promise<FlowType> {
|
||||||
try {
|
try {
|
||||||
const response = await axios.patch(`/api/v1/flows/${updatedFlow.id}`, {
|
const response = await api.patch(`/api/v1/flows/${updatedFlow.id}`, {
|
||||||
name: updatedFlow.name,
|
name: updatedFlow.name,
|
||||||
data: updatedFlow.data,
|
data: updatedFlow.data,
|
||||||
description: updatedFlow.description,
|
description: updatedFlow.description,
|
||||||
|
|
@ -155,7 +155,7 @@ export async function updateFlowInDatabase(
|
||||||
*/
|
*/
|
||||||
export async function readFlowsFromDatabase() {
|
export async function readFlowsFromDatabase() {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get("/api/v1/flows/");
|
const response = await api.get("/api/v1/flows/");
|
||||||
if (response.status !== 200) {
|
if (response.status !== 200) {
|
||||||
throw new Error(`HTTP error! status: ${response.status}`);
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
}
|
}
|
||||||
|
|
@ -168,7 +168,7 @@ export async function readFlowsFromDatabase() {
|
||||||
|
|
||||||
export async function downloadFlowsFromDatabase() {
|
export async function downloadFlowsFromDatabase() {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get("/api/v1/flows/download/");
|
const response = await api.get("/api/v1/flows/download/");
|
||||||
if (response.status !== 200) {
|
if (response.status !== 200) {
|
||||||
throw new Error(`HTTP error! status: ${response.status}`);
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
}
|
}
|
||||||
|
|
@ -181,7 +181,7 @@ export async function downloadFlowsFromDatabase() {
|
||||||
|
|
||||||
export async function uploadFlowsToDatabase(flows) {
|
export async function uploadFlowsToDatabase(flows) {
|
||||||
try {
|
try {
|
||||||
const response = await axios.post(`/api/v1/flows/upload/`, flows);
|
const response = await api.post(`/api/v1/flows/upload/`, flows);
|
||||||
|
|
||||||
if (response.status !== 201) {
|
if (response.status !== 201) {
|
||||||
throw new Error(`HTTP error! status: ${response.status}`);
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
|
|
@ -202,7 +202,7 @@ export async function uploadFlowsToDatabase(flows) {
|
||||||
*/
|
*/
|
||||||
export async function deleteFlowFromDatabase(flowId: string) {
|
export async function deleteFlowFromDatabase(flowId: string) {
|
||||||
try {
|
try {
|
||||||
const response = await axios.delete(`/api/v1/flows/${flowId}`);
|
const response = await api.delete(`/api/v1/flows/${flowId}`);
|
||||||
if (response.status !== 200) {
|
if (response.status !== 200) {
|
||||||
throw new Error(`HTTP error! status: ${response.status}`);
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
}
|
}
|
||||||
|
|
@ -222,7 +222,7 @@ export async function deleteFlowFromDatabase(flowId: string) {
|
||||||
*/
|
*/
|
||||||
export async function getFlowFromDatabase(flowId: number) {
|
export async function getFlowFromDatabase(flowId: number) {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(`/api/v1/flows/${flowId}`);
|
const response = await api.get(`/api/v1/flows/${flowId}`);
|
||||||
if (response.status !== 200) {
|
if (response.status !== 200) {
|
||||||
throw new Error(`HTTP error! status: ${response.status}`);
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
}
|
}
|
||||||
|
|
@ -241,7 +241,7 @@ export async function getFlowFromDatabase(flowId: number) {
|
||||||
*/
|
*/
|
||||||
export async function getFlowStylesFromDatabase() {
|
export async function getFlowStylesFromDatabase() {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get("/api/v1/flow_styles/");
|
const response = await api.get("/api/v1/flow_styles/");
|
||||||
if (response.status !== 200) {
|
if (response.status !== 200) {
|
||||||
throw new Error(`HTTP error! status: ${response.status}`);
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
}
|
}
|
||||||
|
|
@ -261,7 +261,7 @@ export async function getFlowStylesFromDatabase() {
|
||||||
*/
|
*/
|
||||||
export async function saveFlowStyleToDatabase(flowStyle: FlowStyleType) {
|
export async function saveFlowStyleToDatabase(flowStyle: FlowStyleType) {
|
||||||
try {
|
try {
|
||||||
const response = await axios.post("/api/v1/flow_styles/", flowStyle, {
|
const response = await api.post("/api/v1/flow_styles/", flowStyle, {
|
||||||
headers: {
|
headers: {
|
||||||
accept: "application/json",
|
accept: "application/json",
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
|
@ -284,7 +284,7 @@ export async function saveFlowStyleToDatabase(flowStyle: FlowStyleType) {
|
||||||
* @returns {Promise<AxiosResponse<any>>} A promise that resolves to an AxiosResponse containing the version information.
|
* @returns {Promise<AxiosResponse<any>>} A promise that resolves to an AxiosResponse containing the version information.
|
||||||
*/
|
*/
|
||||||
export async function getVersion() {
|
export async function getVersion() {
|
||||||
const respnose = await axios.get("/api/v1/version");
|
const respnose = await api.get("/api/v1/version");
|
||||||
return respnose.data;
|
return respnose.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -294,7 +294,7 @@ export async function getVersion() {
|
||||||
* @returns {Promise<AxiosResponse<any>>} A promise that resolves to an AxiosResponse containing the health status.
|
* @returns {Promise<AxiosResponse<any>>} A promise that resolves to an AxiosResponse containing the health status.
|
||||||
*/
|
*/
|
||||||
export async function getHealth() {
|
export async function getHealth() {
|
||||||
return await axios.get("/health"); // Health is the only endpoint that doesn't require /api/v1
|
return await api.get("/health"); // Health is the only endpoint that doesn't require /api/v1
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -306,7 +306,7 @@ export async function getHealth() {
|
||||||
export async function getBuildStatus(
|
export async function getBuildStatus(
|
||||||
flowId: string
|
flowId: string
|
||||||
): Promise<BuildStatusTypeAPI> {
|
): Promise<BuildStatusTypeAPI> {
|
||||||
return await axios.get(`/api/v1/build/${flowId}/status`);
|
return await api.get(`/api/v1/build/${flowId}/status`);
|
||||||
}
|
}
|
||||||
|
|
||||||
//docs for postbuildinit
|
//docs for postbuildinit
|
||||||
|
|
@ -319,7 +319,7 @@ export async function getBuildStatus(
|
||||||
export async function postBuildInit(
|
export async function postBuildInit(
|
||||||
flow: FlowType
|
flow: FlowType
|
||||||
): Promise<AxiosResponse<InitTypeAPI>> {
|
): Promise<AxiosResponse<InitTypeAPI>> {
|
||||||
return await axios.post(`/api/v1/build/init/${flow.id}`, flow);
|
return await api.post(`/api/v1/build/init/${flow.id}`, flow);
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetch(`/upload/${id}`, {
|
// fetch(`/upload/${id}`, {
|
||||||
|
|
@ -337,5 +337,5 @@ export async function uploadFile(
|
||||||
): Promise<AxiosResponse<UploadFileTypeAPI>> {
|
): Promise<AxiosResponse<UploadFileTypeAPI>> {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("file", file);
|
formData.append("file", file);
|
||||||
return await axios.post(`/api/v1/upload/${id}`, formData);
|
return await api.post(`/api/v1/upload/${id}`, formData);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import App from "./App";
|
||||||
import ContextWrapper from "./contexts";
|
import ContextWrapper from "./contexts";
|
||||||
import reportWebVitals from "./reportWebVitals";
|
import reportWebVitals from "./reportWebVitals";
|
||||||
|
|
||||||
|
import { ApiInterceptor } from "./controllers/API/api";
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
|
|
||||||
const root = ReactDOM.createRoot(
|
const root = ReactDOM.createRoot(
|
||||||
|
|
@ -13,6 +14,7 @@ root.render(
|
||||||
<ContextWrapper>
|
<ContextWrapper>
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<App />
|
<App />
|
||||||
|
<ApiInterceptor />
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
</ContextWrapper>
|
</ContextWrapper>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue