Merge pull request #4336 from Dokploy/fix/template-fetch-timeout-error-handling

fix(templates): add fetch timeout and handle network errors gracefully
This commit is contained in:
Mauricio Siu
2026-04-30 18:52:45 -06:00
committed by GitHub
2 changed files with 43 additions and 44 deletions

View File

@@ -700,11 +700,14 @@ export const composeRouter = createTRPCRouter({
getTags: protectedProcedure
.input(z.object({ baseUrl: z.string().optional() }))
.query(async ({ input }) => {
try {
const githubTemplates = await fetchTemplatesList(input.baseUrl);
const allTags = githubTemplates.flatMap((template) => template.tags);
const uniqueTags = _.uniq(allTags);
return uniqueTags;
return _.uniq(allTags);
} catch (error) {
console.warn("Failed to fetch template tags:", error);
return [];
}
}),
disconnectGitProvider: protectedProcedure
.input(apiFindCompose)

View File

@@ -55,8 +55,9 @@ interface TemplateMetadata {
export async function fetchTemplatesList(
baseUrl = "https://templates.dokploy.com",
): Promise<TemplateMetadata[]> {
try {
const response = await fetch(`${baseUrl}/meta.json`);
const response = await fetch(`${baseUrl}/meta.json`, {
signal: AbortSignal.timeout(10000),
});
if (!response.ok) {
throw new Error(`Failed to fetch templates: ${response.statusText}`);
}
@@ -70,10 +71,6 @@ export async function fetchTemplatesList(
links: template.links,
tags: template.tags,
}));
} catch (error) {
console.error("Error fetching templates list:", error);
throw error;
}
}
/**
@@ -83,11 +80,14 @@ export async function fetchTemplateFiles(
templateId: string,
baseUrl = "https://templates.dokploy.com",
): Promise<{ config: CompleteTemplate; dockerCompose: string }> {
try {
// Fetch both files in parallel
const timeout = AbortSignal.timeout(10000);
const [templateYmlResponse, dockerComposeResponse] = await Promise.all([
fetch(`${baseUrl}/blueprints/${templateId}/template.toml`),
fetch(`${baseUrl}/blueprints/${templateId}/docker-compose.yml`),
fetch(`${baseUrl}/blueprints/${templateId}/template.toml`, {
signal: timeout,
}),
fetch(`${baseUrl}/blueprints/${templateId}/docker-compose.yml`, {
signal: timeout,
}),
]);
if (!templateYmlResponse.ok || !dockerComposeResponse.ok) {
@@ -102,8 +102,4 @@ export async function fetchTemplateFiles(
const config = parse(templateYml) as CompleteTemplate;
return { config, dockerCompose };
} catch (error) {
console.error(`Error fetching template ${templateId}:`, error);
throw error;
}
}