fix(backend/ApNoteService): try retrieving again when failed by duplication (#11472)

* fix(backend/ApNoteService): try retrieving again when failed by duplication

* Update CHANGELOG.md

---------

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
This commit is contained in:
Kagami Sascha Rosylight 2023-08-08 06:26:03 +02:00 committed by GitHub
parent f6a3f6f5f1
commit ec229dbd3b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 20 deletions

View file

@ -29,6 +29,7 @@
### Server ### Server
- cacheRemoteFilesの初期値はfalseになりました - cacheRemoteFilesの初期値はfalseになりました
- 一部のfeatured noteを照会できない問題を修正
- ファイルアップロード時等にファイル名の拡張子を修正する関数(correctFilename)の挙動を改善 - ファイルアップロード時等にファイル名の拡張子を修正する関数(correctFilename)の挙動を改善
- fix: muteがapiからのuser list timeline取得で機能しない問題を修正 - fix: muteがapiからのuser list timeline取得で機能しない問題を修正

View file

@ -131,13 +131,13 @@ export class ApNoteService {
this.logger.debug(`Note fetched: ${JSON.stringify(note, null, 2)}`); this.logger.debug(`Note fetched: ${JSON.stringify(note, null, 2)}`);
if (note.id && !checkHttps(note.id)) { if (note.id && !checkHttps(note.id)) {
throw new Error('unexpected shcema of note.id: ' + note.id); throw new Error('unexpected schema of note.id: ' + note.id);
} }
const url = getOneApHrefNullable(note.url); const url = getOneApHrefNullable(note.url);
if (url && !checkHttps(url)) { if (url && !checkHttps(url)) {
throw new Error('unexpected shcema of note url: ' + url); throw new Error('unexpected schema of note url: ' + url);
} }
this.logger.info(`Creating the Note: ${note.id}`); this.logger.info(`Creating the Note: ${note.id}`);
@ -271,24 +271,36 @@ export class ApNoteService {
const poll = await this.apQuestionService.extractPollFromQuestion(note, resolver).catch(() => undefined); const poll = await this.apQuestionService.extractPollFromQuestion(note, resolver).catch(() => undefined);
return await this.noteCreateService.create(actor, { try {
createdAt: note.published ? new Date(note.published) : null, return await this.noteCreateService.create(actor, {
files, createdAt: note.published ? new Date(note.published) : null,
reply, files,
renote: quote, reply,
name: note.name, renote: quote,
cw, name: note.name,
text, cw,
localOnly: false, text,
visibility, localOnly: false,
visibleUsers, visibility,
apMentions, visibleUsers,
apHashtags, apMentions,
apEmojis, apHashtags,
poll, apEmojis,
uri: note.id, poll,
url: url, uri: note.id,
}, silent); url: url,
}, silent);
} catch (err: any) {
if (err.name !== 'duplicated') {
throw err;
}
this.logger.info('The note is already inserted while creating itself, reading again');
const duplicate = await this.fetchNote(value);
if (!duplicate) {
throw new Error('The note creation failed with duplication error even when there is no duplication');
}
return duplicate;
}
} }
/** /**

View file

@ -259,6 +259,21 @@ describe('ActivityPub', () => {
assert.strictEqual(note.text, 'test test foo'); assert.strictEqual(note.text, 'test test foo');
assert.strictEqual(note.uri, actor2Note.id); assert.strictEqual(note.uri, actor2Note.id);
}); });
test('Fetch a note that is a featured note of the attributed actor', async () => {
const actor = createRandomActor();
actor.featured = `${actor.id}/collections/featured`;
const featured = createRandomFeaturedCollection(actor, 5);
const firstNote = (featured.items as NonTransientIPost[])[0];
resolver.register(actor.id, actor);
resolver.register(actor.featured, featured);
resolver.register(firstNote.id, firstNote);
const note = await noteService.createNote(firstNote.id as string, resolver);
assert.strictEqual(note?.uri, firstNote.id);
});
}); });
describe('Images', () => { describe('Images', () => {