Non-existing dependencies should cause a soft failure

This commit is contained in:
Kir_Antipov 2021-12-11 15:59:39 +03:00
parent af38f88370
commit 2194c72c22
2 changed files with 48 additions and 12 deletions

View file

@ -21,6 +21,13 @@ export default class CurseForgePublisher extends ModPublisher {
protected async publishMod(id: string, token: string, name: string, _version: string, channel: string, loaders: string[], gameVersions: string[], java: string[], changelog: string, files: File[], dependencies: Dependency[]): Promise<void> {
let parentFileId = undefined;
const versions = await convertToCurseForgeVersions(gameVersions, loaders, java, token);
const projects = dependencies
.filter((x, _, self) => x.kind !== DependencyKind.Suggests || !self.find(y => y.id === x.id && y.kind !== DependencyKind.Suggests))
.map(x => ({
slug: x.getProjectSlug(this.target),
type: forgeDependencyKinds.get(x.kind)
}))
.filter(x => x.slug && x.type);
for (const file of files) {
const data = {
@ -30,21 +37,34 @@ export default class CurseForgePublisher extends ModPublisher {
parentFileID: parentFileId,
releaseType: channel,
gameVersions: parentFileId ? undefined : versions,
relations: parentFileId ? undefined : {
projects: dependencies
.filter((x, _, self) => x.kind !== DependencyKind.Suggests || !self.find(y => y.id === x.id && y.kind !== DependencyKind.Suggests))
.map(x => ({
slug: x.getProjectSlug(this.target),
type: forgeDependencyKinds.get(x.kind)
}))
.filter(x => x.slug && x.type)
}
relations: (parentFileId || !projects.length) ? undefined : { projects }
};
const fileId = await uploadFile(id, data, file, token);
const fileId = await this.upload(id, data, file, token);
if (!parentFileId) {
parentFileId = fileId;
}
}
}
private async upload(id: string, data: Record<string, any>, file: File, token: string): Promise<number | never> {
while (true) {
try {
return await uploadFile(id, data, file, token);
} catch (error) {
if (error?.info?.errorCode === 1018 && typeof error.info.errorMessage === "string") {
const match = error.info.errorMessage.match(/Invalid slug in project relations: '([^']+)'/);
const projects = <{ slug: string }[]>data.relations?.projects;
if (match && projects?.length) {
const invalidSlugIndex = projects.findIndex(x => x.slug === match[1]);
if (invalidSlugIndex !== -1) {
projects.splice(invalidSlugIndex, 1);
continue;
}
}
}
throw error;
}
}
}
}

View file

@ -19,6 +19,20 @@ interface CurseForgeVersions {
java: CurseForgeVersion[];
}
interface CurseForgeUploadErrorInfo {
errorCode: number;
errorMessage: string;
}
class CurseForgeUploadError extends Error {
public readonly info?: CurseForgeUploadErrorInfo;
constructor(message: string, info?: CurseForgeUploadErrorInfo) {
super(message);
this.info = info;
}
}
let cachedCurseForgeVersions: CurseForgeVersions = null;
async function getCurseForgeVersions(token: string): Promise<CurseForgeVersions> {
@ -98,10 +112,12 @@ export async function uploadFile(id: string, data: Record<string, any>, file: Fi
if (!response.ok) {
let errorText = response.statusText;
let info: CurseForgeUploadErrorInfo;
try {
errorText += `, ${await response.text()}`;
info = <CurseForgeUploadErrorInfo>await response.json();
errorText += `, ${JSON.stringify(info)}`;
} catch { }
throw new Error(`Failed to upload file: ${response.status} (${errorText})`);
throw new CurseForgeUploadError(`Failed to upload file: ${response.status} (${errorText})`, info);
}
return (<{ id: number }>await response.json()).id;