mirror of
https://codeberg.org/yeentown/barkey.git
synced 2025-07-07 12:36:57 +00:00
add more details to IdentifiableErrors
This commit is contained in:
parent
687de6f2f0
commit
4540614f7b
8 changed files with 40 additions and 40 deletions
|
@ -80,15 +80,15 @@ export class BunnyService {
|
|||
});
|
||||
|
||||
req.on('error', (error) => {
|
||||
this.bunnyCdnLogger.error(error);
|
||||
this.bunnyCdnLogger.error('Unhandled error', error);
|
||||
data.destroy();
|
||||
throw new IdentifiableError('689ee33f-f97c-479a-ac49-1b9f8140bf91', 'An error has occured during the connectiong to BunnyCDN');
|
||||
throw new IdentifiableError('689ee33f-f97c-479a-ac49-1b9f8140bf91', 'An error has occurred while connecting to BunnyCDN', true, error);
|
||||
});
|
||||
|
||||
data.pipe(req).on('finish', () => {
|
||||
data.destroy();
|
||||
});
|
||||
|
||||
|
||||
// wait till stream gets destroyed upon finish of piping to prevent the UI from showing the upload as success way too early
|
||||
await finished(data);
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ export class NotePiningService {
|
|||
});
|
||||
|
||||
if (note == null) {
|
||||
throw new IdentifiableError('70c4e51f-5bea-449c-a030-53bee3cce202', 'No such note.');
|
||||
throw new IdentifiableError('70c4e51f-5bea-449c-a030-53bee3cce202', `Note ${noteId} does not exist`);
|
||||
}
|
||||
|
||||
await this.db.transaction(async tem => {
|
||||
|
@ -102,7 +102,7 @@ export class NotePiningService {
|
|||
});
|
||||
|
||||
if (note == null) {
|
||||
throw new IdentifiableError('b302d4cf-c050-400a-bbb3-be208681f40c', 'No such note.');
|
||||
throw new IdentifiableError('b302d4cf-c050-400a-bbb3-be208681f40c', `Note ${noteId} does not exist`);
|
||||
}
|
||||
|
||||
this.userNotePiningsRepository.delete({
|
||||
|
|
|
@ -117,7 +117,7 @@ export class ReactionService {
|
|||
if (note.userId !== user.id) {
|
||||
const blocked = await this.userBlockingService.checkBlocked(note.userId, user.id);
|
||||
if (blocked) {
|
||||
throw new IdentifiableError('e70412a4-7197-4726-8e74-f3e0deb92aa7');
|
||||
throw new IdentifiableError('e70412a4-7197-4726-8e74-f3e0deb92aa7', 'Note not accessible for you.');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -322,14 +322,14 @@ export class ReactionService {
|
|||
});
|
||||
|
||||
if (exist == null) {
|
||||
throw new IdentifiableError('60527ec9-b4cb-4a88-a6bd-32d3ad26817d', 'not reacted');
|
||||
throw new IdentifiableError('60527ec9-b4cb-4a88-a6bd-32d3ad26817d', 'reaction does not exist');
|
||||
}
|
||||
|
||||
// Delete reaction
|
||||
const result = await this.noteReactionsRepository.delete(exist.id);
|
||||
|
||||
if (result.affected !== 1) {
|
||||
throw new IdentifiableError('60527ec9-b4cb-4a88-a6bd-32d3ad26817d', 'not reacted');
|
||||
throw new IdentifiableError('60527ec9-b4cb-4a88-a6bd-32d3ad26817d', 'reaction does not exist');
|
||||
}
|
||||
|
||||
// Decrement reactions count
|
||||
|
|
|
@ -79,7 +79,7 @@ export class Resolver {
|
|||
if (isCollectionOrOrderedCollection(collection)) {
|
||||
return collection;
|
||||
} else {
|
||||
throw new IdentifiableError('f100eccf-f347-43fb-9b45-96a0831fb635', `unrecognized collection type: ${collection.type}`);
|
||||
throw new IdentifiableError('f100eccf-f347-43fb-9b45-96a0831fb635', `collection ${getApId(value)} has unsupported type: ${collection.type}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -276,15 +276,15 @@ export class Resolver {
|
|||
// URLs with fragment parts cannot be resolved correctly because
|
||||
// the fragment part does not get transmitted over HTTP(S).
|
||||
// Avoid strange behaviour by not trying to resolve these at all.
|
||||
throw new IdentifiableError('b94fd5b1-0e3b-4678-9df2-dad4cd515ab2', `cannot resolve URL with fragment: ${value}`);
|
||||
throw new IdentifiableError('b94fd5b1-0e3b-4678-9df2-dad4cd515ab2', `failed to resolve ${value}: URL contains fragment`);
|
||||
}
|
||||
|
||||
if (this.history.has(value)) {
|
||||
throw new IdentifiableError('0dc86cf6-7cd6-4e56-b1e6-5903d62d7ea5', `cannot resolve already resolved URL: ${value}`);
|
||||
throw new IdentifiableError('0dc86cf6-7cd6-4e56-b1e6-5903d62d7ea5', `failed to resolve ${value}: recursive resolution blocked`);
|
||||
}
|
||||
|
||||
if (this.history.size > this.recursionLimit) {
|
||||
throw new IdentifiableError('d592da9f-822f-4d91-83d7-4ceefabcf3d2', `hit recursion limit: ${value}`);
|
||||
throw new IdentifiableError('d592da9f-822f-4d91-83d7-4ceefabcf3d2', `failed to resolve ${value}: hit recursion limit`);
|
||||
}
|
||||
|
||||
this.history.add(value);
|
||||
|
@ -294,7 +294,7 @@ export class Resolver {
|
|||
}
|
||||
|
||||
if (!this.utilityService.isFederationAllowedHost(host)) {
|
||||
throw new IdentifiableError('09d79f9e-64f1-4316-9cfa-e75c4d091574', `cannot fetch AP object ${value}: blocked instance ${host}`);
|
||||
throw new IdentifiableError('09d79f9e-64f1-4316-9cfa-e75c4d091574', `failed to resolve ${value}: instance ${host} is blocked`);
|
||||
}
|
||||
|
||||
if (this.config.signToActivityPubGet && !this.user) {
|
||||
|
@ -324,7 +324,7 @@ export class Resolver {
|
|||
!(object['@context'] as unknown[]).includes('https://www.w3.org/ns/activitystreams') :
|
||||
object['@context'] !== 'https://www.w3.org/ns/activitystreams'
|
||||
) {
|
||||
throw new IdentifiableError('72180409-793c-4973-868e-5a118eb5519b', `invalid AP object ${value}: does not have ActivityStreams context`);
|
||||
throw new IdentifiableError('72180409-793c-4973-868e-5a118eb5519b', `failed to resolve ${value}: response does not have ActivityStreams context`);
|
||||
}
|
||||
|
||||
// The object ID is already validated to match the final URL's authority by signedGet / getActivityJson.
|
||||
|
@ -340,7 +340,7 @@ export class Resolver {
|
|||
|
||||
// Check if the redirect bounce from [allowed domain] to [blocked domain].
|
||||
if (!this.utilityService.isFederationAllowedHost(finalHost)) {
|
||||
throw new IdentifiableError('0a72bf24-2d9b-4f1d-886b-15aaa31adeda', `cannot fetch AP object ${value}: redirected to blocked instance ${finalHost}`);
|
||||
throw new IdentifiableError('0a72bf24-2d9b-4f1d-886b-15aaa31adeda', `failed to resolve ${value}: redirected to blocked instance ${finalHost}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -350,7 +350,7 @@ export class Resolver {
|
|||
@bindThis
|
||||
private resolveLocal(url: string): Promise<IObjectWithId> {
|
||||
const parsed = this.apDbResolverService.parseUri(url);
|
||||
if (!parsed.local) throw new IdentifiableError('02b40cd0-fa92-4b0c-acc9-fb2ada952ab8', `resolveLocal - not a local URL: ${url}`);
|
||||
if (!parsed.local) throw new IdentifiableError('02b40cd0-fa92-4b0c-acc9-fb2ada952ab8', `failed to resolve local ${url}: not a local URL`);
|
||||
|
||||
switch (parsed.type) {
|
||||
case 'notes':
|
||||
|
@ -380,7 +380,7 @@ export class Resolver {
|
|||
case 'follows':
|
||||
return this.followRequestsRepository.findOneBy({ id: parsed.id })
|
||||
.then(async followRequest => {
|
||||
if (followRequest == null) throw new IdentifiableError('a9d946e5-d276-47f8-95fb-f04230289bb0', `resolveLocal - invalid follow request ID ${parsed.id}: ${url}`);
|
||||
if (followRequest == null) throw new IdentifiableError('a9d946e5-d276-47f8-95fb-f04230289bb0', `failed to resolve local ${url}: invalid follow request ID`);
|
||||
const [follower, followee] = await Promise.all([
|
||||
this.usersRepository.findOneBy({
|
||||
id: followRequest.followerId,
|
||||
|
@ -392,12 +392,12 @@ export class Resolver {
|
|||
}),
|
||||
]);
|
||||
if (follower == null || followee == null) {
|
||||
throw new IdentifiableError('06ae3170-1796-4d93-a697-2611ea6d83b6', `resolveLocal - follower or followee does not exist: ${url}`);
|
||||
throw new IdentifiableError('06ae3170-1796-4d93-a697-2611ea6d83b6', `failed to resolve local ${url}: follower or followee does not exist`);
|
||||
}
|
||||
return this.apRendererService.addContext(this.apRendererService.renderFollow(follower as MiLocalUser | MiRemoteUser, followee as MiLocalUser | MiRemoteUser, url));
|
||||
});
|
||||
default:
|
||||
throw new IdentifiableError('7a5d2fc0-94bc-4db6-b8b8-1bf24a2e23d0', `resolveLocal: type ${parsed.type} unhandled: ${url}`);
|
||||
throw new IdentifiableError('7a5d2fc0-94bc-4db6-b8b8-1bf24a2e23d0', `failed to resolve local ${url}: unsupported type ${parsed.type}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ export function validateContentTypeSetAsActivityPub(response: Response): void {
|
|||
const contentType = (response.headers.get('content-type') ?? '').toLowerCase();
|
||||
|
||||
if (contentType === '') {
|
||||
throw new IdentifiableError('d09dc850-b76c-4f45-875a-7389339d78b8', `invalid content type of AP response - no content-type header: ${response.url}`, true);
|
||||
throw new IdentifiableError('d09dc850-b76c-4f45-875a-7389339d78b8', `invalid AP response from ${response.url}: no content-type header`, true);
|
||||
}
|
||||
if (
|
||||
contentType.startsWith('application/activity+json') ||
|
||||
|
@ -20,7 +20,7 @@ export function validateContentTypeSetAsActivityPub(response: Response): void {
|
|||
) {
|
||||
return;
|
||||
}
|
||||
throw new IdentifiableError('dc110060-a5f2-461d-808b-39c62702ca64', `invalid content type of AP response - content type "${contentType}" is not application/activity+json or application/ld+json: ${response.url}`);
|
||||
throw new IdentifiableError('dc110060-a5f2-461d-808b-39c62702ca64', `invalid AP response from ${response.url}: content type "${contentType}" is not application/activity+json or application/ld+json`);
|
||||
}
|
||||
|
||||
const plusJsonSuffixRegex = /^\s*(application|text)\/[a-zA-Z0-9\.\-\+]+\+json\s*(;|$)/;
|
||||
|
@ -29,7 +29,7 @@ export function validateContentTypeSetAsJsonLD(response: Response): void {
|
|||
const contentType = (response.headers.get('content-type') ?? '').toLowerCase();
|
||||
|
||||
if (contentType === '') {
|
||||
throw new IdentifiableError('45793ab7-7648-4886-b503-429f8a0d0f73', `invalid content type of JSON LD - no content-type header: ${response.url}`, true);
|
||||
throw new IdentifiableError('45793ab7-7648-4886-b503-429f8a0d0f73', `invalid AP response from ${response.url}: no content-type header`, true);
|
||||
}
|
||||
if (
|
||||
contentType.startsWith('application/ld+json') ||
|
||||
|
@ -38,5 +38,5 @@ export function validateContentTypeSetAsJsonLD(response: Response): void {
|
|||
) {
|
||||
return;
|
||||
}
|
||||
throw new IdentifiableError('4bf8f36b-4d33-4ac9-ad76-63fa11f354e9', `invalid content type of JSON LD - content type "${contentType}" is not application/ld+json or application/json: ${response.url}`);
|
||||
throw new IdentifiableError('4bf8f36b-4d33-4ac9-ad76-63fa11f354e9', `invalid AP response from ${response.url}: content type "${contentType}" is not application/ld+json or application/json`);
|
||||
}
|
||||
|
|
|
@ -101,29 +101,29 @@ export class ApNoteService {
|
|||
const apType = getApType(object);
|
||||
|
||||
if (apType == null || !validPost.includes(apType)) {
|
||||
return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', `invalid Note: invalid object type ${apType ?? 'undefined'}`);
|
||||
return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', `invalid Note from ${uri}: invalid object type ${apType ?? 'undefined'}`);
|
||||
}
|
||||
|
||||
if (object.id && this.utilityService.extractDbHost(object.id) !== expectHost) {
|
||||
return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', `invalid Note: id has different host. expected: ${expectHost}, actual: ${this.utilityService.extractDbHost(object.id)}`);
|
||||
return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', `invalid Note from ${uri}: id has different host. expected: ${expectHost}, actual: ${this.utilityService.extractDbHost(object.id)}`);
|
||||
}
|
||||
|
||||
const actualHost = object.attributedTo && this.utilityService.extractDbHost(getOneApId(object.attributedTo));
|
||||
if (object.attributedTo && actualHost !== expectHost) {
|
||||
return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', `invalid Note: attributedTo has different host. expected: ${expectHost}, actual: ${actualHost}`);
|
||||
return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', `invalid Note from ${uri}: attributedTo has different host. expected: ${expectHost}, actual: ${actualHost}`);
|
||||
}
|
||||
|
||||
if (object.published && !this.idService.isSafeT(new Date(object.published).valueOf())) {
|
||||
return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', 'invalid Note: published timestamp is malformed');
|
||||
return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', 'invalid Note from ${uri}: published timestamp is malformed');
|
||||
}
|
||||
|
||||
if (actor) {
|
||||
const attribution = (object.attributedTo) ? getOneApId(object.attributedTo) : actor.uri;
|
||||
if (attribution !== actor.uri) {
|
||||
return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', `invalid Note: attribution does not match the actor that send it. attribution: ${attribution}, actor: ${actor.uri}`);
|
||||
return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', `invalid Note from ${uri}: attribution does not match the actor that send it. attribution: ${attribution}, actor: ${actor.uri}`);
|
||||
}
|
||||
if (user && attribution !== user.uri) {
|
||||
return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', `invalid Note: updated attribution does not match original attribution. updated attribution: ${user.uri}, original attribution: ${attribution}`);
|
||||
return new IdentifiableError('d450b8a9-48e4-4dab-ae36-f4db763fda7c', `invalid Note from ${uri}: updated attribution does not match original attribution. updated attribution: ${user.uri}, original attribution: ${attribution}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -197,7 +197,7 @@ export class ApNoteService {
|
|||
// eslint-disable-next-line no-param-reassign
|
||||
actor ??= await this.apPersonService.fetchPerson(uri) as MiRemoteUser | undefined;
|
||||
if (actor && actor.isSuspended) {
|
||||
throw new IdentifiableError('85ab9bd7-3a41-4530-959d-f07073900109', `actor ${uri} has been suspended: ${entryUri}`);
|
||||
throw new IdentifiableError('85ab9bd7-3a41-4530-959d-f07073900109', `failed to create note ${entryUri}: actor ${uri} has been suspended`);
|
||||
}
|
||||
|
||||
const apMentions = await this.apMentionService.extractApMentions(note.tag, resolver);
|
||||
|
@ -224,7 +224,7 @@ export class ApNoteService {
|
|||
*/
|
||||
const hasProhibitedWords = this.noteCreateService.checkProhibitedWordsContain({ cw, text, pollChoices: poll?.choices });
|
||||
if (hasProhibitedWords) {
|
||||
throw new IdentifiableError('689ee33f-f97c-479a-ac49-1b9f8140af99', `Note contains prohibited words: ${entryUri}`);
|
||||
throw new IdentifiableError('689ee33f-f97c-479a-ac49-1b9f8140af99', `failed to create note ${entryUri}: contains prohibited words`);
|
||||
}
|
||||
//#endregion
|
||||
|
||||
|
@ -233,7 +233,7 @@ export class ApNoteService {
|
|||
|
||||
// 解決した投稿者が凍結されていたらスキップ
|
||||
if (actor.isSuspended) {
|
||||
throw new IdentifiableError('85ab9bd7-3a41-4530-959d-f07073900109', `actor has been suspended: ${entryUri}`);
|
||||
throw new IdentifiableError('85ab9bd7-3a41-4530-959d-f07073900109', `failed to create note ${entryUri}: actor ${actor.id} has been suspended`);
|
||||
}
|
||||
|
||||
const noteAudience = await this.apAudienceService.parseAudience(actor, note.to, note.cc, resolver);
|
||||
|
@ -409,7 +409,7 @@ export class ApNoteService {
|
|||
this.logger.info(`Creating the Note: ${note.id}`);
|
||||
|
||||
if (actor.isSuspended) {
|
||||
throw new IdentifiableError('85ab9bd7-3a41-4530-959d-f07073900109', `actor ${actor.id} has been suspended: ${noteUri}`);
|
||||
throw new IdentifiableError('85ab9bd7-3a41-4530-959d-f07073900109', `failed to update note ${entryUri}: actor ${actor.id} has been suspended`);
|
||||
}
|
||||
|
||||
const apMentions = await this.apMentionService.extractApMentions(note.tag, resolver);
|
||||
|
@ -436,7 +436,7 @@ export class ApNoteService {
|
|||
*/
|
||||
const hasProhibitedWords = this.noteCreateService.checkProhibitedWordsContain({ cw, text, pollChoices: poll?.choices });
|
||||
if (hasProhibitedWords) {
|
||||
throw new IdentifiableError('689ee33f-f97c-479a-ac49-1b9f8140af99', `Note contains prohibited words: ${noteUri}`);
|
||||
throw new IdentifiableError('689ee33f-f97c-479a-ac49-1b9f8140af99', `failed to update note ${noteUri}: contains prohibited words`);
|
||||
}
|
||||
//#endregion
|
||||
|
||||
|
|
|
@ -15,8 +15,8 @@ export class IdentifiableError extends Error {
|
|||
*/
|
||||
public readonly isRetryable: boolean;
|
||||
|
||||
constructor(id: string, message?: string, isRetryable = false) {
|
||||
super(message);
|
||||
constructor(id: string, message?: string, isRetryable = false, options?: ErrorOptions) {
|
||||
super(message, options);
|
||||
this.message = message ?? '';
|
||||
this.id = id;
|
||||
this.isRetryable = isRetryable;
|
||||
|
|
|
@ -36,7 +36,7 @@ export class GetterService {
|
|||
const note = await this.notesRepository.findOneBy({ id: noteId });
|
||||
|
||||
if (note == null) {
|
||||
throw new IdentifiableError('9725d0ce-ba28-4dde-95a7-2cbb2c15de24', 'No such note.');
|
||||
throw new IdentifiableError('9725d0ce-ba28-4dde-95a7-2cbb2c15de24', `Note ${noteId} does not exist`);
|
||||
}
|
||||
|
||||
return note;
|
||||
|
@ -47,7 +47,7 @@ export class GetterService {
|
|||
const note = await this.notesRepository.findOne({ where: { id: noteId }, relations: ['user'] });
|
||||
|
||||
if (note == null) {
|
||||
throw new IdentifiableError('9725d0ce-ba28-4dde-95a7-2cbb2c15de24', 'No such note.');
|
||||
throw new IdentifiableError('9725d0ce-ba28-4dde-95a7-2cbb2c15de24', `Note ${noteId} does not exist`);
|
||||
}
|
||||
|
||||
return note;
|
||||
|
@ -59,7 +59,7 @@ export class GetterService {
|
|||
@bindThis
|
||||
public async getEdits(noteId: MiNote['id']) {
|
||||
const edits = await this.noteEditRepository.findBy({ noteId: noteId }).catch(() => {
|
||||
throw new IdentifiableError('9725d0ce-ba28-4dde-95a7-2cbb2c15de24', 'No such note.');
|
||||
throw new IdentifiableError('9725d0ce-ba28-4dde-95a7-2cbb2c15de24', `Note ${noteId} does not exist`);
|
||||
});
|
||||
|
||||
return edits;
|
||||
|
@ -73,7 +73,7 @@ export class GetterService {
|
|||
const user = await this.usersRepository.findOneBy({ id: userId });
|
||||
|
||||
if (user == null) {
|
||||
throw new IdentifiableError('15348ddd-432d-49c2-8a5a-8069753becff', 'No such user.');
|
||||
throw new IdentifiableError('15348ddd-432d-49c2-8a5a-8069753becff', `User ${userId} does not exist`);
|
||||
}
|
||||
|
||||
return user as MiLocalUser | MiRemoteUser;
|
||||
|
|
Loading…
Add table
Reference in a new issue