server: refactor ApiError to store error descriptions centrally

The UUIDs are no longer used for errors and all errors should now have
a descriptive message attached to them. Also, all errors should now have
the proper HTTP status code for a reply instead of the generic 400 and 500
response codes. Because the errors all have more specific error codes, the
"kind" of client or server is also abolished.
This commit is contained in:
Johann150 2022-10-20 23:04:24 +02:00
parent 66d7b69377
commit 934ee82b8f
Signed by untrusted user: Johann150
GPG key ID: 9EE6577A2A06F8F1
139 changed files with 768 additions and 2241 deletions

View file

@ -13,7 +13,7 @@ export async function handler(endpoint: IEndpoint, ctx: Koa.Context): Promise<vo
: ctx.request.body; : ctx.request.body;
const error = (e: ApiError): void => { const error = (e: ApiError): void => {
ctx.status = e.httpStatusCode ?? 500; ctx.status = e.httpStatusCode;
if (e.httpStatusCode === 401) { if (e.httpStatusCode === 401) {
ctx.response.set('WWW-Authenticate', 'Bearer'); ctx.response.set('WWW-Authenticate', 'Bearer');
} }
@ -47,12 +47,7 @@ export async function handler(endpoint: IEndpoint, ctx: Koa.Context): Promise<vo
}); });
}).catch(e => { }).catch(e => {
if (e instanceof AuthenticationError) { if (e instanceof AuthenticationError) {
error({ error(new ApiError('AUTHENTICATION_FAILED', e.message));
message: 'Authentication failed: ' + e.message,
code: 'AUTHENTICATION_FAILED',
id: 'b0a7f5f8-dc2f-4171-b91f-de88ad238e14',
httpStatusCode: 401,
});
} else { } else {
error(new ApiError()); error(new ApiError());
} }

View file

@ -8,29 +8,16 @@ import endpoints, { IEndpointMeta } from './endpoints.js';
import { ApiError } from './error.js'; import { ApiError } from './error.js';
import { apiLogger } from './logger.js'; import { apiLogger } from './logger.js';
const accessDenied = {
message: 'Access denied.',
code: 'ACCESS_DENIED',
id: '56f35758-7dd5-468b-8439-5d6fb8ec9b8e',
};
export default async (endpoint: string, user: CacheableLocalUser | null | undefined, token: AccessToken | null | undefined, data: any, ctx?: Koa.Context) => { export default async (endpoint: string, user: CacheableLocalUser | null | undefined, token: AccessToken | null | undefined, data: any, ctx?: Koa.Context) => {
const isSecure = user != null && token == null; const isSecure = user != null && token == null;
const isModerator = user != null && (user.isModerator || user.isAdmin); const isModerator = user != null && (user.isModerator || user.isAdmin);
const ep = endpoints.find(e => e.name === endpoint); const ep = endpoints.find(e => e.name === endpoint);
if (ep == null) { if (ep == null) throw new ApiError('NO_SUCH_ENDPOINT');
throw new ApiError({
message: 'No such endpoint.',
code: 'NO_SUCH_ENDPOINT',
id: 'f8080b67-5f9c-4eb7-8c18-7f1eeae8f709',
httpStatusCode: 404,
});
}
if (ep.meta.secure && !isSecure) { if (ep.meta.secure && !isSecure) {
throw new ApiError(accessDenied); throw new ApiError('ACCESS_DENIED', 'This operation can only be performed with a native token.');
} }
if (ep.meta.limit && !isModerator) { if (ep.meta.limit && !isModerator) {
@ -50,47 +37,28 @@ export default async (endpoint: string, user: CacheableLocalUser | null | undefi
// Rate limit // Rate limit
await limiter(limit as IEndpointMeta['limit'] & { key: NonNullable<string> }, limitActor).catch(e => { await limiter(limit as IEndpointMeta['limit'] & { key: NonNullable<string> }, limitActor).catch(e => {
throw new ApiError({ throw new ApiError('RATE_LIMIT_EXCEEDED');
message: 'Rate limit exceeded. Please try again later.',
code: 'RATE_LIMIT_EXCEEDED',
id: 'd5826d14-3982-4d2e-8011-b9e9f02499ef',
httpStatusCode: 429,
});
}); });
} }
if (ep.meta.requireCredential && user == null) { if (ep.meta.requireCredential && user == null) {
throw new ApiError({ throw new ApiError('AUTHENTICATION_REQUIRED');
message: 'Credential required.',
code: 'CREDENTIAL_REQUIRED',
id: '1384574d-a912-4b81-8601-c7b1c4085df1',
httpStatusCode: 401,
});
} }
if (ep.meta.requireCredential && user!.isSuspended) { if (ep.meta.requireCredential && user!.isSuspended) {
throw new ApiError({ throw new ApiError('SUSPENDED');
message: 'Your account has been suspended.',
code: 'YOUR_ACCOUNT_SUSPENDED',
id: 'a8c724b3-6e9c-4b46-b1a8-bc3ed6258370',
httpStatusCode: 403,
});
} }
if (ep.meta.requireAdmin && !user!.isAdmin) { if (ep.meta.requireAdmin && !user!.isAdmin) {
throw new ApiError(accessDenied, { reason: 'You are not the admin.' }); throw new ApiError('ACCESS_DENIED', 'This operation requires administrator privileges.');
} }
if (ep.meta.requireModerator && !isModerator) { if (ep.meta.requireModerator && !isModerator) {
throw new ApiError(accessDenied, { reason: 'You are not a moderator.' }); throw new ApiError('ACCESS_DENIED', 'This operation requires moderator privileges.');
} }
if (token && ep.meta.kind && !token.permission.some(p => p === ep.meta.kind)) { if (token && ep.meta.kind && !token.permission.some(p => p === ep.meta.kind)) {
throw new ApiError({ throw new ApiError('ACCESS_DENIED', 'This operation requires privileges which this token does not grant.');
message: 'Your app does not have the necessary permissions to use this endpoint.',
code: 'PERMISSION_DENIED',
id: '1370e5b7-d4eb-4566-bb1d-7748ee6a1838',
});
} }
// Cast non JSON input // Cast non JSON input
@ -101,11 +69,7 @@ export default async (endpoint: string, user: CacheableLocalUser | null | undefi
try { try {
data[k] = JSON.parse(data[k]); data[k] = JSON.parse(data[k]);
} catch (e) { } catch (e) {
throw new ApiError({ throw new ApiError('INVALID_PARAM', {
message: 'Invalid param.',
code: 'INVALID_PARAM',
id: '0b5f1631-7c1a-41a6-b399-cce335f34d85',
}, {
param: k, param: k,
reason: `cannot cast to ${param.type}`, reason: `cannot cast to ${param.type}`,
}); });
@ -129,7 +93,7 @@ export default async (endpoint: string, user: CacheableLocalUser | null | undefi
stack: e.stack, stack: e.stack,
}, },
}); });
throw new ApiError(null, { throw new ApiError('INTERNAL_ERROR', {
e: { e: {
message: e.message, message: e.message,
code: e.name, code: e.name,

View file

@ -24,25 +24,13 @@ export async function signup(opts: {
// Validate username // Validate username
if (!Users.validateLocalUsername(username)) { if (!Users.validateLocalUsername(username)) {
throw new ApiError({ throw new ApiError('INVALID_USERNAME');
message: 'This username is invalid.',
code: 'INVALID_USERNAME',
id: 'ece89f3c-d845-4d9a-850b-1735285e8cd4',
kind: 'client',
httpStatusCode: 400,
});
} }
if (password != null && passwordHash == null) { if (password != null && passwordHash == null) {
// Validate password // Validate password
if (!Users.validatePassword(password)) { if (!Users.validatePassword(password)) {
throw new ApiError({ throw new ApiError('INVALID_PASSWORD');
message: 'This password is invalid.',
code: 'INVALID_PASSWORD',
id: 'a941905b-fe7b-43e2-8ecd-50ad3a2287ab',
kind: 'client',
httpStatusCode: 400,
});
} }
// Generate hash of password // Generate hash of password
@ -53,22 +41,14 @@ export async function signup(opts: {
// Generate secret // Generate secret
const secret = generateUserToken(); const secret = generateUserToken();
const duplicateUsernameError = {
message: 'This username is not available.',
code: 'USED_USERNAME',
id: '7ddd595e-6860-4593-93c5-9fdbcb80cd81',
kind: 'client',
httpStatusCode: 409,
};
// Check username duplication // Check username duplication
if (await Users.findOneBy({ usernameLower: username.toLowerCase(), host: IsNull() })) { if (await Users.findOneBy({ usernameLower: username.toLowerCase(), host: IsNull() })) {
throw new ApiError(duplicateUsernameError); throw new ApiError('USED_USERNAME');
} }
// Check deleted username duplication // Check deleted username duplication
if (await UsedUsernames.findOneBy({ username: username.toLowerCase() })) { if (await UsedUsernames.findOneBy({ username: username.toLowerCase() })) {
throw new ApiError(duplicateUsernameError); throw new ApiError('USED_USERNAME');
} }
const keyPair = await new Promise<string[]>((res, rej) => const keyPair = await new Promise<string[]>((res, rej) =>
@ -97,7 +77,7 @@ export async function signup(opts: {
host: IsNull(), host: IsNull(),
}); });
if (exist) throw new ApiError(duplicateUsernameError); if (exist) throw new ApiError('USED_USERNAME');
account = await transactionalEntityManager.save(new User({ account = await transactionalEntityManager.save(new User({
id: genId(), id: genId(),

View file

@ -28,22 +28,16 @@ export default function <T extends IEndpointMeta, Ps extends Schema>(meta: T, pa
fs.unlink(file.path, () => {}); fs.unlink(file.path, () => {});
} }
if (meta.requireFile && file == null) return Promise.reject(new ApiError({ if (meta.requireFile && file == null) {
message: 'File required.', return Promise.reject(new ApiError('FILE_REQUIRED'));
code: 'FILE_REQUIRED', }
id: '4267801e-70d1-416a-b011-4ee502885d8b',
}));
const valid = validate(params); const valid = validate(params);
if (!valid) { if (!valid) {
if (file) cleanup(); if (file) cleanup();
const errors = validate.errors!; const errors = validate.errors!;
const err = new ApiError({ const err = new ApiError('INVALID_PARAM', {
message: 'Invalid param.',
code: 'INVALID_PARAM',
id: '3d81ceae-475f-4600-b2a8-2bc116157532',
}, {
param: errors[0].schemaPath, param: errors[0].schemaPath,
reason: errors[0].message, reason: errors[0].message,
}); });

View file

@ -8,13 +8,7 @@ export const meta = {
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
errors: { errors: ['NO_SUCH_ANNOUNCEMENT'],
noSuchAnnouncement: {
message: 'No such announcement.',
code: 'NO_SUCH_ANNOUNCEMENT',
id: 'ecad8040-a276-4e85-bda9-015a708d291e',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -29,7 +23,7 @@ export const paramDef = {
export default define(meta, paramDef, async (ps, me) => { export default define(meta, paramDef, async (ps, me) => {
const announcement = await Announcements.findOneBy({ id: ps.id }); const announcement = await Announcements.findOneBy({ id: ps.id });
if (announcement == null) throw new ApiError(meta.errors.noSuchAnnouncement); if (announcement == null) throw new ApiError('NO_SUCH_ANNOUNCEMENT');
await Announcements.delete(announcement.id); await Announcements.delete(announcement.id);
}); });

View file

@ -8,13 +8,7 @@ export const meta = {
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
errors: { errors: ['NO_SUCH_ANNOUNCEMENT'],
noSuchAnnouncement: {
message: 'No such announcement.',
code: 'NO_SUCH_ANNOUNCEMENT',
id: 'd3aae5a7-6372-4cb4-b61c-f511ffc2d7cc',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -32,7 +26,7 @@ export const paramDef = {
export default define(meta, paramDef, async (ps, me) => { export default define(meta, paramDef, async (ps, me) => {
const announcement = await Announcements.findOneBy({ id: ps.id }); const announcement = await Announcements.findOneBy({ id: ps.id });
if (announcement == null) throw new ApiError(meta.errors.noSuchAnnouncement); if (announcement == null) throw new ApiError('NO_SUCH_ANNOUNCEMENT');
await Announcements.update(announcement.id, { await Announcements.update(announcement.id, {
updatedAt: new Date(), updatedAt: new Date(),

View file

@ -8,13 +8,7 @@ export const meta = {
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
errors: { errors: ['NO_SUCH_FILE'],
noSuchFile: {
message: 'No such file.',
code: 'NO_SUCH_FILE',
id: 'caf3ca38-c6e5-472e-a30c-b05377dcc240',
},
},
res: { res: {
type: 'object', type: 'object',
@ -180,9 +174,7 @@ export default define(meta, paramDef, async (ps, me) => {
}], }],
}); });
if (file == null) { if (file == null) throw new ApiError('NO_SUCH_FILE');
throw new ApiError(meta.errors.noSuchFile);
}
return file; return file;
}); });

View file

@ -13,13 +13,7 @@ export const meta = {
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
errors: { errors: ['NO_SUCH_FILE'],
noSuchFile: {
message: 'No such file.',
code: 'NO_SUCH_FILE',
id: 'fc46b5a4-6b92-4c33-ac66-b806659bb5cf',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -34,7 +28,7 @@ export const paramDef = {
export default define(meta, paramDef, async (ps, me) => { export default define(meta, paramDef, async (ps, me) => {
const file = await DriveFiles.findOneBy({ id: ps.fileId }); const file = await DriveFiles.findOneBy({ id: ps.fileId });
if (file == null) throw new ApiError(meta.errors.noSuchFile); if (file == null) throw new ApiError('NO_SUCH_FILE');
const name = file.name.split('.')[0].match(/^[a-z0-9_]+$/) ? file.name.split('.')[0] : `_${rndstr('a-z0-9', 8)}_`; const name = file.name.split('.')[0].match(/^[a-z0-9_]+$/) ? file.name.split('.')[0] : `_${rndstr('a-z0-9', 8)}_`;

View file

@ -13,13 +13,7 @@ export const meta = {
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
errors: { errors: ['NO_SUCH_EMOJI', 'INTERNAL_ERROR'],
noSuchEmoji: {
message: 'No such emoji.',
code: 'NO_SUCH_EMOJI',
id: 'e2785b66-dca3-4087-9cac-b93c541cc425',
},
},
res: { res: {
type: 'object', type: 'object',
@ -46,9 +40,7 @@ export const paramDef = {
export default define(meta, paramDef, async (ps, me) => { export default define(meta, paramDef, async (ps, me) => {
const emoji = await Emojis.findOneBy({ id: ps.emojiId }); const emoji = await Emojis.findOneBy({ id: ps.emojiId });
if (emoji == null) { if (emoji == null) throw new ApiError('NO_SUCH_EMOJI');
throw new ApiError(meta.errors.noSuchEmoji);
}
let driveFile: DriveFile; let driveFile: DriveFile;
@ -56,7 +48,7 @@ export default define(meta, paramDef, async (ps, me) => {
// Create file // Create file
driveFile = await uploadFromUrl({ url: emoji.originalUrl, user: null, force: true }); driveFile = await uploadFromUrl({ url: emoji.originalUrl, user: null, force: true });
} catch (e) { } catch (e) {
throw new ApiError(); throw new ApiError('INTERNAL_ERROR', e);
} }
const copied = await Emojis.insert({ const copied = await Emojis.insert({

View file

@ -10,13 +10,7 @@ export const meta = {
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
errors: { errors: ['NO_SUCH_EMOJI'],
noSuchEmoji: {
message: 'No such emoji.',
code: 'NO_SUCH_EMOJI',
id: 'be83669b-773a-44b7-b1f8-e5e5170ac3c2',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -31,7 +25,7 @@ export const paramDef = {
export default define(meta, paramDef, async (ps, me) => { export default define(meta, paramDef, async (ps, me) => {
const emoji = await Emojis.findOneBy({ id: ps.id }); const emoji = await Emojis.findOneBy({ id: ps.id });
if (emoji == null) throw new ApiError(meta.errors.noSuchEmoji); if (emoji == null) throw new ApiError('NO_SUCH_EMOJI');
await Emojis.delete(emoji.id); await Emojis.delete(emoji.id);

View file

@ -9,13 +9,7 @@ export const meta = {
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
errors: { errors: ['NO_SUCH_EMOJI'],
noSuchEmoji: {
message: 'No such emoji.',
code: 'NO_SUCH_EMOJI',
id: '684dec9d-a8c2-4364-9aa8-456c49cb1dc8',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -39,7 +33,7 @@ export const paramDef = {
export default define(meta, paramDef, async (ps) => { export default define(meta, paramDef, async (ps) => {
const emoji = await Emojis.findOneBy({ id: ps.id }); const emoji = await Emojis.findOneBy({ id: ps.id });
if (emoji == null) throw new ApiError(meta.errors.noSuchEmoji); if (emoji == null) throw new ApiError('NO_SUCH_EMOJI');
await Emojis.update(emoji.id, { await Emojis.update(emoji.id, {
updatedAt: new Date(), updatedAt: new Date(),

View file

@ -9,13 +9,7 @@ export const meta = {
requireCredential: true, requireCredential: true,
requireModerator: true, requireModerator: true,
errors: { errors: ['INVALID_URL'],
invalidUrl: {
message: 'Invalid URL',
code: 'INVALID_URL',
id: 'fb8c92d3-d4e5-44e7-b3d4-800d5cef8b2c',
},
},
res: { res: {
type: 'object', type: 'object',
@ -58,8 +52,8 @@ export const paramDef = {
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
try { try {
if (new URL(ps.inbox).protocol !== 'https:') throw new Error('https only'); if (new URL(ps.inbox).protocol !== 'https:') throw new Error('https only');
} catch { } catch (e) {
throw new ApiError(meta.errors.invalidUrl); throw new ApiError('INVALID_URL', e);
} }
return await addRelay(ps.inbox); return await addRelay(ps.inbox);

View file

@ -11,19 +11,7 @@ export const meta = {
kind: 'write:account', kind: 'write:account',
errors: { errors: ['NO_SUCH_USER_LIST', 'NO_SUCH_GROUP'],
noSuchUserList: {
message: 'No such user list.',
code: 'NO_SUCH_USER_LIST',
id: '95063e93-a283-4b8b-9aa5-bcdb8df69a7f',
},
noSuchUserGroup: {
message: 'No such user group.',
code: 'NO_SUCH_USER_GROUP',
id: 'aa3c0b9a-8cae-47c0-92ac-202ce5906682',
},
},
res: { res: {
type: 'object', type: 'object',
@ -71,18 +59,14 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (userList == null) { if (userList == null) throw new ApiError('NO_SUCH_USER_LIST');
throw new ApiError(meta.errors.noSuchUserList);
}
} else if (ps.src === 'group' && ps.userGroupId) { } else if (ps.src === 'group' && ps.userGroupId) {
userGroupJoining = await UserGroupJoinings.findOneBy({ userGroupJoining = await UserGroupJoinings.findOneBy({
userGroupId: ps.userGroupId, userGroupId: ps.userGroupId,
userId: user.id, userId: user.id,
}); });
if (userGroupJoining == null) { if (userGroupJoining == null) throw new ApiError('NO_SUCH_GROUP');
throw new ApiError(meta.errors.noSuchUserGroup);
}
} }
const antenna = await Antennas.insert({ const antenna = await Antennas.insert({

View file

@ -10,13 +10,7 @@ export const meta = {
kind: 'write:account', kind: 'write:account',
errors: { errors: ['NO_SUCH_ANTENNA'],
noSuchAntenna: {
message: 'No such antenna.',
code: 'NO_SUCH_ANTENNA',
id: 'b34dcf9d-348f-44bb-99d0-6c9314cfe2df',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -34,9 +28,7 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (antenna == null) { if (antenna == null) throw new ApiError('NO_SUCH_ANTENNA');
throw new ApiError(meta.errors.noSuchAntenna);
}
await Antennas.delete(antenna.id); await Antennas.delete(antenna.id);

View file

@ -14,13 +14,7 @@ export const meta = {
kind: 'read:account', kind: 'read:account',
errors: { errors: ['NO_SUCH_ANTENNA'],
noSuchAntenna: {
message: 'No such antenna.',
code: 'NO_SUCH_ANTENNA',
id: '850926e0-fd3b-49b6-b69a-b28a5dbd82fe',
},
},
res: { res: {
type: 'array', type: 'array',
@ -53,9 +47,7 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (antenna == null) { if (antenna == null) throw new ApiError('NO_SUCH_ANTENNA');
throw new ApiError(meta.errors.noSuchAntenna);
}
const query = makePaginationQuery(Notes.createQueryBuilder('note'), const query = makePaginationQuery(Notes.createQueryBuilder('note'),
ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate)

View file

@ -9,13 +9,7 @@ export const meta = {
kind: 'read:account', kind: 'read:account',
errors: { errors: ['NO_SUCH_ANTENNA'],
noSuchAntenna: {
message: 'No such antenna.',
code: 'NO_SUCH_ANTENNA',
id: 'c06569fb-b025-4f23-b22d-1fcd20d2816b',
},
},
res: { res: {
type: 'object', type: 'object',
@ -40,9 +34,7 @@ export default define(meta, paramDef, async (ps, me) => {
userId: me.id, userId: me.id,
}); });
if (antenna == null) { if (antenna == null) throw new ApiError('NO_SUCH_ANTENNA');
throw new ApiError(meta.errors.noSuchAntenna);
}
return await Antennas.pack(antenna); return await Antennas.pack(antenna);
}); });

View file

@ -10,25 +10,7 @@ export const meta = {
kind: 'write:account', kind: 'write:account',
errors: { errors: ['NO_SUCH_ANTENNA', 'NO_SUCH_USER_LIST', 'NO_SUCH_GROUP'],
noSuchAntenna: {
message: 'No such antenna.',
code: 'NO_SUCH_ANTENNA',
id: '10c673ac-8852-48eb-aa1f-f5b67f069290',
},
noSuchUserList: {
message: 'No such user list.',
code: 'NO_SUCH_USER_LIST',
id: '1c6b35c9-943e-48c2-81e4-2844989407f7',
},
noSuchUserGroup: {
message: 'No such user group.',
code: 'NO_SUCH_USER_GROUP',
id: '109ed789-b6eb-456e-b8a9-6059d567d385',
},
},
res: { res: {
type: 'object', type: 'object',
@ -74,9 +56,7 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (antenna == null) { if (antenna == null) throw new ApiError('NO_SUCH_ANTENNA');
throw new ApiError(meta.errors.noSuchAntenna);
}
let userList; let userList;
let userGroupJoining; let userGroupJoining;
@ -87,18 +67,14 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (userList == null) { if (userList == null) throw new ApiError('NO_SUCH_USER_LIST');
throw new ApiError(meta.errors.noSuchUserList);
}
} else if (ps.src === 'group' && ps.userGroupId) { } else if (ps.src === 'group' && ps.userGroupId) {
userGroupJoining = await UserGroupJoinings.findOneBy({ userGroupJoining = await UserGroupJoinings.findOneBy({
userGroupId: ps.userGroupId, userGroupId: ps.userGroupId,
userId: user.id, userId: user.id,
}); });
if (userGroupJoining == null) { if (userGroupJoining == null) throw new ApiError('NO_SUCH_GROUP');
throw new ApiError(meta.errors.noSuchUserGroup);
}
} }
await Antennas.update(antenna.id, { await Antennas.update(antenna.id, {

View file

@ -12,9 +12,6 @@ export const meta = {
max: 30, max: 30,
}, },
errors: {
},
res: { res: {
type: 'object', type: 'object',
optional: false, nullable: false, optional: false, nullable: false,

View file

@ -24,13 +24,7 @@ export const meta = {
max: 30, max: 30,
}, },
errors: { errors: ['NO_SUCH_OBJECT'],
noSuchObject: {
message: 'No such object.',
code: 'NO_SUCH_OBJECT',
id: 'dc94d745-1262-4e63-a17d-fecaa57efc82',
},
},
res: { res: {
optional: false, nullable: false, optional: false, nullable: false,
@ -83,7 +77,7 @@ export default define(meta, paramDef, async (ps, me) => {
if (object) { if (object) {
return object; return object;
} else { } else {
throw new ApiError(meta.errors.noSuchObject); throw new ApiError('NO_SUCH_OBJECT');
} }
}); });

View file

@ -5,13 +5,7 @@ import { ApiError } from '../../error.js';
export const meta = { export const meta = {
tags: ['app'], tags: ['app'],
errors: { errors: ['NO_SUCH_APP'],
noSuchApp: {
message: 'No such app.',
code: 'NO_SUCH_APP',
id: 'dce83913-2dc6-4093-8a7b-71dbb11718a3',
},
},
res: { res: {
type: 'object', type: 'object',
@ -33,14 +27,12 @@ export default define(meta, paramDef, async (ps, user, token) => {
const isSecure = user != null && token == null; const isSecure = user != null && token == null;
// Lookup app // Lookup app
const ap = await Apps.findOneBy({ id: ps.appId }); const app = await Apps.findOneBy({ id: ps.appId });
if (ap == null) { if (app == null) throw new ApiError('NO_SUCH_APP');
throw new ApiError(meta.errors.noSuchApp);
}
return await Apps.pack(ap, user, { return await Apps.pack(app, user, {
detail: true, detail: true,
includeSecret: isSecure && (ap.userId === user!.id), includeSecret: isSecure && (app.userId === user!.id),
}); });
}); });

View file

@ -12,13 +12,7 @@ export const meta = {
secure: true, secure: true,
errors: { errors: ['NO_SUCH_SESSION'],
noSuchSession: {
message: 'No such session.',
code: 'NO_SUCH_SESSION',
id: '9c72d8de-391a-43c1-9d06-08d29efde8df',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -35,9 +29,7 @@ export default define(meta, paramDef, async (ps, user) => {
const session = await AuthSessions const session = await AuthSessions
.findOneBy({ token: ps.token }); .findOneBy({ token: ps.token });
if (session == null) { if (session == null) throw new ApiError('NO_SUCH_SESSION');
throw new ApiError(meta.errors.noSuchSession);
}
// Generate access token // Generate access token
const accessToken = secureRndstr(32, true); const accessToken = secureRndstr(32, true);

View file

@ -26,13 +26,7 @@ export const meta = {
}, },
}, },
errors: { errors: ['NO_SUCH_APP'],
noSuchApp: {
message: 'No such app.',
code: 'NO_SUCH_APP',
id: '92f93e63-428e-4f2f-a5a4-39e1407fe998',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -51,7 +45,7 @@ export default define(meta, paramDef, async (ps) => {
}); });
if (app == null) { if (app == null) {
throw new ApiError(meta.errors.noSuchApp); throw new ApiError('NO_SUCH_APP');
} }
// Generate token // Generate token

View file

@ -7,13 +7,7 @@ export const meta = {
requireCredential: false, requireCredential: false,
errors: { errors: ['NO_SUCH_SESSION'],
noSuchSession: {
message: 'No such session.',
code: 'NO_SUCH_SESSION',
id: 'bd72c97d-eba7-4adb-a467-f171b8847250',
},
},
res: { res: {
type: 'object', type: 'object',
@ -52,9 +46,7 @@ export default define(meta, paramDef, async (ps, user) => {
token: ps.token, token: ps.token,
}); });
if (session == null) { if (session == null) throw new ApiError('NO_SUCH_SESSION');
throw new ApiError(meta.errors.noSuchSession);
}
return await AuthSessions.pack(session, user); return await AuthSessions.pack(session, user);
}); });

View file

@ -24,25 +24,7 @@ export const meta = {
}, },
}, },
errors: { errors: ['NO_SUCH_APP', 'NO_SUCH_SESSION', 'PENDING_SESSION'],
noSuchApp: {
message: 'No such app.',
code: 'NO_SUCH_APP',
id: 'fcab192a-2c5a-43b7-8ad8-9b7054d8d40d',
},
noSuchSession: {
message: 'No such session.',
code: 'NO_SUCH_SESSION',
id: '5b5a1503-8bc8-4bd0-8054-dc189e8cdcb3',
},
pendingSession: {
message: 'This session is not completed yet.',
code: 'PENDING_SESSION',
id: '8c8a4145-02cc-4cca-8e66-29ba60445a8e',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -61,9 +43,7 @@ export default define(meta, paramDef, async (ps) => {
secret: ps.appSecret, secret: ps.appSecret,
}); });
if (app == null) { if (app == null) throw new ApiError('NO_SUCH_APP');
throw new ApiError(meta.errors.noSuchApp);
}
// Fetch token // Fetch token
const session = await AuthSessions.findOneBy({ const session = await AuthSessions.findOneBy({
@ -71,13 +51,9 @@ export default define(meta, paramDef, async (ps) => {
appId: app.id, appId: app.id,
}); });
if (session == null) { if (session == null) throw new ApiError('NO_SUCH_SESSION');
throw new ApiError(meta.errors.noSuchSession);
}
if (session.userId == null) { if (session.userId == null) throw new ApiError('PENDING_SESSION');
throw new ApiError(meta.errors.pendingSession);
}
// Lookup access token // Lookup access token
const accessToken = await AccessTokens.findOneByOrFail({ const accessToken = await AccessTokens.findOneByOrFail({

View file

@ -17,25 +17,7 @@ export const meta = {
kind: 'write:blocks', kind: 'write:blocks',
errors: { errors: ['NO_SUCH_USER', 'BLOCKEE_IS_YOURSELF', 'ALREADY_BLOCKING'],
noSuchUser: {
message: 'No such user.',
code: 'NO_SUCH_USER',
id: '7cc4f851-e2f1-4621-9633-ec9e1d00c01e',
},
blockeeIsYourself: {
message: 'Blockee is yourself.',
code: 'BLOCKEE_IS_YOURSELF',
id: '88b19138-f28d-42c0-8499-6a31bbd0fdc6',
},
alreadyBlocking: {
message: 'You are already blocking that user.',
code: 'ALREADY_BLOCKING',
id: '787fed64-acb9-464a-82eb-afbd745b9614',
},
},
res: { res: {
type: 'object', type: 'object',
@ -57,13 +39,11 @@ export default define(meta, paramDef, async (ps, user) => {
const blocker = await Users.findOneByOrFail({ id: user.id }); const blocker = await Users.findOneByOrFail({ id: user.id });
// 自分自身 // 自分自身
if (user.id === ps.userId) { if (user.id === ps.userId) throw new ApiError('BLOCKEE_IS_YOURSELF');
throw new ApiError(meta.errors.blockeeIsYourself);
}
// Get blockee // Get blockee
const blockee = await getUser(ps.userId).catch(e => { const blockee = await getUser(ps.userId).catch(e => {
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError('NO_SUCH_USER');
throw e; throw e;
}); });
@ -73,9 +53,7 @@ export default define(meta, paramDef, async (ps, user) => {
blockeeId: blockee.id, blockeeId: blockee.id,
}); });
if (exist != null) { if (exist != null) throw new ApiError('ALREADY_BLOCKING');
throw new ApiError(meta.errors.alreadyBlocking);
}
await create(blocker, blockee); await create(blocker, blockee);

View file

@ -17,25 +17,7 @@ export const meta = {
kind: 'write:blocks', kind: 'write:blocks',
errors: { errors: ['NO_SUCH_USER', 'BLOCKEE_IS_YOURSELF', 'NOT_BLOCKING'],
noSuchUser: {
message: 'No such user.',
code: 'NO_SUCH_USER',
id: '8621d8bf-c358-4303-a066-5ea78610eb3f',
},
blockeeIsYourself: {
message: 'Blockee is yourself.',
code: 'BLOCKEE_IS_YOURSELF',
id: '06f6fac6-524b-473c-a354-e97a40ae6eac',
},
notBlocking: {
message: 'You are not blocking that user.',
code: 'NOT_BLOCKING',
id: '291b2efa-60c6-45c0-9f6a-045c8f9b02cd',
},
},
res: { res: {
type: 'object', type: 'object',
@ -54,16 +36,14 @@ export const paramDef = {
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
const blocker = await Users.findOneByOrFail({ id: user.id });
// Check if the blockee is yourself // Check if the blockee is yourself
if (user.id === ps.userId) { if (user.id === ps.userId) throw new ApiError('BLOCKEE_IS_YOURSELF');
throw new ApiError(meta.errors.blockeeIsYourself);
} const blocker = await Users.findOneByOrFail({ id: user.id });
// Get blockee // Get blockee
const blockee = await getUser(ps.userId).catch(e => { const blockee = await getUser(ps.userId).catch(e => {
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError('NO_SUCH_USER');
throw e; throw e;
}); });
@ -73,9 +53,7 @@ export default define(meta, paramDef, async (ps, user) => {
blockeeId: blockee.id, blockeeId: blockee.id,
}); });
if (exist == null) { if (exist == null) throw new ApiError('NOT_BLOCKING');
throw new ApiError(meta.errors.notBlocking);
}
// Delete blocking // Delete blocking
await deleteBlocking(blocker, blockee); await deleteBlocking(blocker, blockee);

View file

@ -17,13 +17,7 @@ export const meta = {
ref: 'Channel', ref: 'Channel',
}, },
errors: { errors: ['NO_SUCH_FILE'],
noSuchFile: {
message: 'No such file.',
code: 'NO_SUCH_FILE',
id: 'cd1e9f3e-5a12-4ab4-96f6-5d0a2cc32050',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -45,9 +39,7 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (banner == null) { if (banner == null) throw new ApiError('NO_SUCH_FILE');
throw new ApiError(meta.errors.noSuchFile);
}
} }
const channel = await Channels.insert({ const channel = await Channels.insert({

View file

@ -11,13 +11,7 @@ export const meta = {
kind: 'write:channels', kind: 'write:channels',
errors: { errors: ['NO_SUCH_CHANNEL'],
noSuchChannel: {
message: 'No such channel.',
code: 'NO_SUCH_CHANNEL',
id: 'c0031718-d573-4e85-928e-10039f1fbb68',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -34,9 +28,7 @@ export default define(meta, paramDef, async (ps, user) => {
id: ps.channelId, id: ps.channelId,
}); });
if (channel == null) { if (channel == null) throw new ApiError('NO_SUCH_CHANNEL');
throw new ApiError(meta.errors.noSuchChannel);
}
await ChannelFollowings.insert({ await ChannelFollowings.insert({
id: genId(), id: genId(),

View file

@ -13,13 +13,7 @@ export const meta = {
ref: 'Channel', ref: 'Channel',
}, },
errors: { errors: ['NO_SUCH_CHANNEL'],
noSuchChannel: {
message: 'No such channel.',
code: 'NO_SUCH_CHANNEL',
id: '6f6c314b-7486-4897-8966-c04a66a02923',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -36,9 +30,7 @@ export default define(meta, paramDef, async (ps, me) => {
id: ps.channelId, id: ps.channelId,
}); });
if (channel == null) { if (channel == null) throw new ApiError('NO_SUCH_CHANNEL');
throw new ApiError(meta.errors.noSuchChannel);
}
return await Channels.pack(channel, me); return await Channels.pack(channel, me);
}); });

View file

@ -19,13 +19,7 @@ export const meta = {
}, },
}, },
errors: { errors: ['NO_SUCH_CHANNEL'],
noSuchChannel: {
message: 'No such channel.',
code: 'NO_SUCH_CHANNEL',
id: '4d0eeeba-a02c-4c3c-9966-ef60d38d2e7f',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -47,9 +41,7 @@ export default define(meta, paramDef, async (ps, user) => {
id: ps.channelId, id: ps.channelId,
}); });
if (channel == null) { if (channel == null) throw new ApiError('NO_SUCH_CHANNEL');
throw new ApiError(meta.errors.noSuchChannel);
}
//#region Construct query //#region Construct query
const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate) const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId, ps.sinceDate, ps.untilDate)

View file

@ -10,13 +10,7 @@ export const meta = {
kind: 'write:channels', kind: 'write:channels',
errors: { errors: ['NO_SUCH_CHANNEL'],
noSuchChannel: {
message: 'No such channel.',
code: 'NO_SUCH_CHANNEL',
id: '19959ee9-0153-4c51-bbd9-a98c49dc59d6',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -33,9 +27,7 @@ export default define(meta, paramDef, async (ps, user) => {
id: ps.channelId, id: ps.channelId,
}); });
if (channel == null) { if (channel == null) throw new ApiError('NO_SUCH_CHANNEL');
throw new ApiError(meta.errors.noSuchChannel);
}
await ChannelFollowings.delete({ await ChannelFollowings.delete({
followerId: user.id, followerId: user.id,

View file

@ -15,25 +15,7 @@ export const meta = {
ref: 'Channel', ref: 'Channel',
}, },
errors: { errors: ['ACCESS_DENIED', 'NO_SUCH_CHANNEL', 'NO_SUCH_FILE'],
noSuchChannel: {
message: 'No such channel.',
code: 'NO_SUCH_CHANNEL',
id: 'f9c5467f-d492-4c3c-9a8d-a70dacc86512',
},
accessDenied: {
message: 'You do not have edit privilege of the channel.',
code: 'ACCESS_DENIED',
id: '1fb7cb09-d46a-4fdf-b8df-057788cce513',
},
noSuchFile: {
message: 'No such file.',
code: 'NO_SUCH_FILE',
id: 'e86c14a4-0da2-4032-8df3-e737a04c7f3b',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -53,13 +35,9 @@ export default define(meta, paramDef, async (ps, me) => {
id: ps.channelId, id: ps.channelId,
}); });
if (channel == null) { if (channel == null) throw new ApiError('NO_SUCH_CHANNEL');
throw new ApiError(meta.errors.noSuchChannel);
}
if (channel.userId !== me.id) { if (channel.userId !== me.id) throw new ApiError('ACCESS_DENIED', 'You are not the owner of this channel.');
throw new ApiError(meta.errors.accessDenied);
}
// eslint:disable-next-line:no-unnecessary-initializer // eslint:disable-next-line:no-unnecessary-initializer
let banner = undefined; let banner = undefined;
@ -69,9 +47,7 @@ export default define(meta, paramDef, async (ps, me) => {
userId: me.id, userId: me.id,
}); });
if (banner == null) { if (banner == null) throw new ApiError('NO_SUCH_FILE');
throw new ApiError(meta.errors.noSuchFile);
}
} else if (ps.bannerId === null) { } else if (ps.bannerId === null) {
banner = null; banner = null;
} }

View file

@ -11,25 +11,7 @@ export const meta = {
kind: 'write:account', kind: 'write:account',
errors: { errors: ['ALREADY_CLIPPED', 'NO_SUCH_CLIP', 'NO_SUCH_NOTE'],
noSuchClip: {
message: 'No such clip.',
code: 'NO_SUCH_CLIP',
id: 'd6e76cc0-a1b5-4c7c-a287-73fa9c716dcf',
},
noSuchNote: {
message: 'No such note.',
code: 'NO_SUCH_NOTE',
id: 'fc8c0b49-c7a3-4664-a0a6-b418d386bb8b',
},
alreadyClipped: {
message: 'The note has already been clipped.',
code: 'ALREADY_CLIPPED',
id: '734806c4-542c-463a-9311-15c512803965',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -48,12 +30,10 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (clip == null) { if (clip == null) throw new ApiError('NO_SUCH_CLIP');
throw new ApiError(meta.errors.noSuchClip);
}
const note = await getNote(ps.noteId, user).catch(err => { const note = await getNote(ps.noteId, user).catch(err => {
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
throw err; throw err;
}); });
@ -62,9 +42,7 @@ export default define(meta, paramDef, async (ps, user) => {
clipId: clip.id, clipId: clip.id,
}); });
if (exist != null) { if (exist != null) throw new ApiError('ALREADY_CLIPPED');
throw new ApiError(meta.errors.alreadyClipped);
}
await ClipNotes.insert({ await ClipNotes.insert({
id: genId(), id: genId(),

View file

@ -9,13 +9,7 @@ export const meta = {
kind: 'write:account', kind: 'write:account',
errors: { errors: ['NO_SUCH_CLIP'],
noSuchClip: {
message: 'No such clip.',
code: 'NO_SUCH_CLIP',
id: '70ca08ba-6865-4630-b6fb-8494759aa754',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -33,9 +27,7 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (clip == null) { if (clip == null) throw new ApiError('NO_SUCH_CLIP');
throw new ApiError(meta.errors.noSuchClip);
}
await Clips.delete(clip.id); await Clips.delete(clip.id);
}); });

View file

@ -13,13 +13,7 @@ export const meta = {
kind: 'read:account', kind: 'read:account',
errors: { errors: ['NO_SUCH_CLIP'],
noSuchClip: {
message: 'No such clip.',
code: 'NO_SUCH_CLIP',
id: '1d7645e6-2b6d-4635-b0fe-fe22b0e72e00',
},
},
res: { res: {
type: 'array', type: 'array',
@ -49,12 +43,10 @@ export default define(meta, paramDef, async (ps, user) => {
id: ps.clipId, id: ps.clipId,
}); });
if (clip == null) { if (clip == null) throw new ApiError('NO_SUCH_CLIP');
throw new ApiError(meta.errors.noSuchClip);
}
if (!clip.isPublic && (user == null || (clip.userId !== user.id))) { if (!clip.isPublic && (user == null || (clip.userId !== user.id))) {
throw new ApiError(meta.errors.noSuchClip); throw new ApiError('NO_SUCH_CLIP');
} }
const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId) const query = makePaginationQuery(Notes.createQueryBuilder('note'), ps.sinceId, ps.untilId)

View file

@ -10,26 +10,7 @@ export const meta = {
kind: 'write:account', kind: 'write:account',
errors: { errors: ['NO_SUCH_CLIP', 'NO_SUCH_NOTE', 'NOT_CLIPPED'],
noSuchClip: {
message: 'No such clip.',
code: 'NO_SUCH_CLIP',
id: 'b80525c6-97f7-49d7-a42d-ebccd49cfd52',
},
noSuchNote: {
message: 'No such note.',
code: 'NO_SUCH_NOTE',
id: 'aff017de-190e-434b-893e-33a9ff5049d8',
},
notClipped: {
message: 'That note is not added to this clip.',
code: 'NOT_CLIPPED',
id: '6b20c697-6e51-4120-b340-0e47899c7a20',
httpStatusCode: 409,
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -48,12 +29,10 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (clip == null) { if (clip == null) throw new ApiError('NO_SUCH_CLIP');
throw new ApiError(meta.errors.noSuchClip);
}
const note = await getNote(ps.noteId).catch(e => { const note = await getNote(ps.noteId).catch(e => {
if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
throw e; throw e;
}); });
@ -62,7 +41,5 @@ export default define(meta, paramDef, async (ps, user) => {
clipId: clip.id, clipId: clip.id,
}); });
if (affected === 0) { if (affected === 0) throw new ApiError('NOT_CLIPPED');
throw new ApiError(meta.errors.notClipped);
}
}); });

View file

@ -9,13 +9,7 @@ export const meta = {
kind: 'read:account', kind: 'read:account',
errors: { errors: ['NO_SUCH_CLIP'],
noSuchClip: {
message: 'No such clip.',
code: 'NO_SUCH_CLIP',
id: 'c3c5fe33-d62c-44d2-9ea5-d997703f5c20',
},
},
res: { res: {
type: 'object', type: 'object',
@ -39,12 +33,10 @@ export default define(meta, paramDef, async (ps, me) => {
id: ps.clipId, id: ps.clipId,
}); });
if (clip == null) { if (clip == null) throw new ApiError('NO_SUCH_CLIP');
throw new ApiError(meta.errors.noSuchClip);
}
if (!clip.isPublic && (me == null || (clip.userId !== me.id))) { if (!clip.isPublic && (me == null || (clip.userId !== me.id))) {
throw new ApiError(meta.errors.noSuchClip); throw new ApiError('NO_SUCH_CLIP');
} }
return await Clips.pack(clip); return await Clips.pack(clip);

View file

@ -9,13 +9,7 @@ export const meta = {
kind: 'write:account', kind: 'write:account',
errors: { errors: ['NO_SUCH_CLIP'],
noSuchClip: {
message: 'No such clip.',
code: 'NO_SUCH_CLIP',
id: 'b4d92d70-b216-46fa-9a3f-a8c811699257',
},
},
res: { res: {
type: 'object', type: 'object',
@ -43,9 +37,7 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (clip == null) { if (clip == null) throw new ApiError('NO_SUCH_CLIP');
throw new ApiError(meta.errors.noSuchClip);
}
await Clips.update(clip.id, { await Clips.update(clip.id, {
name: ps.name, name: ps.name,

View file

@ -21,13 +21,7 @@ export const meta = {
}, },
}, },
errors: { errors: ['NO_SUCH_FILE'],
noSuchFile: {
message: 'No such file.',
code: 'NO_SUCH_FILE',
id: 'c118ece3-2e4b-4296-99d1-51756e32d232',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -46,9 +40,7 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (file == null) { if (file == null) throw new ApiError('NO_SUCH_FILE');
throw new ApiError(meta.errors.noSuchFile);
}
const notes = await Notes.createQueryBuilder('note') const notes = await Notes.createQueryBuilder('note')
.where(':file = ANY(note.fileIds)', { file: file.id }) .where(':file = ANY(note.fileIds)', { file: file.id })

View file

@ -28,13 +28,7 @@ export const meta = {
ref: 'DriveFile', ref: 'DriveFile',
}, },
errors: { errors: ['INTERNAL_ERROR', 'INVALID_FILE_NAME'],
invalidFileName: {
message: 'Invalid file name.',
code: 'INVALID_FILE_NAME',
id: 'f449b209-0c60-4e51-84d5-29486263bfd4',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -60,7 +54,7 @@ export default define(meta, paramDef, async (ps, user, _, file, cleanup) => {
} else if (name === 'blob') { } else if (name === 'blob') {
name = null; name = null;
} else if (!DriveFiles.validateFileName(name)) { } else if (!DriveFiles.validateFileName(name)) {
throw new ApiError(meta.errors.invalidFileName); throw new ApiError('INVALID_FILE_NAME');
} }
} else { } else {
name = null; name = null;
@ -74,7 +68,7 @@ export default define(meta, paramDef, async (ps, user, _, file, cleanup) => {
if (e instanceof Error || typeof e === 'string') { if (e instanceof Error || typeof e === 'string') {
apiLogger.error(e); apiLogger.error(e);
} }
throw new ApiError(); throw new ApiError('INTERNAL_ERROR');
} finally { } finally {
cleanup!(); cleanup!();
} }

View file

@ -13,19 +13,7 @@ export const meta = {
description: 'Delete an existing drive file.', description: 'Delete an existing drive file.',
errors: { errors: ['ACCESS_DENIED', 'NO_SUCH_FILE'],
noSuchFile: {
message: 'No such file.',
code: 'NO_SUCH_FILE',
id: '908939ec-e52b-4458-b395-1025195cea58',
},
accessDenied: {
message: 'Access denied.',
code: 'ACCESS_DENIED',
id: '5eb8d909-2540-4970-90b8-dd6f86088121',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -40,12 +28,10 @@ export const paramDef = {
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
const file = await DriveFiles.findOneBy({ id: ps.fileId }); const file = await DriveFiles.findOneBy({ id: ps.fileId });
if (file == null) { if (file == null) throw new ApiError('NO_SUCH_FILE');
throw new ApiError(meta.errors.noSuchFile);
}
if ((!user.isAdmin && !user.isModerator) && (file.userId !== user.id)) { if ((!user.isAdmin && !user.isModerator) && (file.userId !== user.id)) {
throw new ApiError(meta.errors.accessDenied); throw new ApiError('ACCESS_DENIED');
} }
// Delete // Delete

View file

@ -18,19 +18,7 @@ export const meta = {
ref: 'DriveFile', ref: 'DriveFile',
}, },
errors: { errors: ['ACCESS_DENIED', 'NO_SUCH_FILE'],
noSuchFile: {
message: 'No such file.',
code: 'NO_SUCH_FILE',
id: '067bc436-2718-4795-b0fb-ecbe43949e31',
},
accessDenied: {
message: 'Access denied.',
code: 'ACCESS_DENIED',
id: '25b73c73-68b1-41d0-bad1-381cfdf6579f',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -69,12 +57,10 @@ export default define(meta, paramDef, async (ps, user) => {
}); });
} }
if (file == null) { if (file == null) throw new ApiError('NO_SUCH_FILE');
throw new ApiError(meta.errors.noSuchFile);
}
if ((!user.isAdmin && !user.isModerator) && (file.userId !== user.id)) { if ((!user.isAdmin && !user.isModerator) && (file.userId !== user.id)) {
throw new ApiError(meta.errors.accessDenied); throw new ApiError('ACCESS_DENIED');
} }
return await DriveFiles.pack(file, { return await DriveFiles.pack(file, {

View file

@ -12,31 +12,7 @@ export const meta = {
description: 'Update the properties of a drive file.', description: 'Update the properties of a drive file.',
errors: { errors: ['ACCESS_DENIED', 'INVALID_FILE_NAME', 'NO_SUCH_FILE', 'NO_SUCH_FOLDER'],
invalidFileName: {
message: 'Invalid file name.',
code: 'INVALID_FILE_NAME',
id: '395e7156-f9f0-475e-af89-53c3c23080c2',
},
noSuchFile: {
message: 'No such file.',
code: 'NO_SUCH_FILE',
id: 'e7778c7e-3af9-49cd-9690-6dbc3e6c972d',
},
accessDenied: {
message: 'Access denied.',
code: 'ACCESS_DENIED',
id: '01a53b27-82fc-445b-a0c1-b558465a8ed2',
},
noSuchFolder: {
message: 'No such folder.',
code: 'NO_SUCH_FOLDER',
id: 'ea8fb7a5-af77-4a08-b608-c0218176cd73',
},
},
res: { res: {
type: 'object', type: 'object',
@ -61,17 +37,15 @@ export const paramDef = {
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
const file = await DriveFiles.findOneBy({ id: ps.fileId }); const file = await DriveFiles.findOneBy({ id: ps.fileId });
if (file == null) { if (file == null) throw new ApiError('NO_SUCH_FILE');
throw new ApiError(meta.errors.noSuchFile);
}
if ((!user.isAdmin && !user.isModerator) && (file.userId !== user.id)) { if ((!user.isAdmin && !user.isModerator) && (file.userId !== user.id)) {
throw new ApiError(meta.errors.accessDenied); throw new ApiError('ACCESS_DENIED');
} }
if (ps.name) file.name = ps.name; if (ps.name) file.name = ps.name;
if (!DriveFiles.validateFileName(file.name)) { if (!DriveFiles.validateFileName(file.name)) {
throw new ApiError(meta.errors.invalidFileName); throw new ApiError('INVALID_FILE_NAME');
} }
if (ps.comment !== undefined) file.comment = ps.comment; if (ps.comment !== undefined) file.comment = ps.comment;
@ -87,9 +61,7 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (folder == null) { if (folder == null) throw new ApiError('NO_SUCH_FOLDER');
throw new ApiError(meta.errors.noSuchFolder);
}
file.folderId = folder.id; file.folderId = folder.id;
} }

View file

@ -11,13 +11,7 @@ export const meta = {
kind: 'write:drive', kind: 'write:drive',
errors: { errors: ['NO_SUCH_FOLDER'],
noSuchFolder: {
message: 'No such folder.',
code: 'NO_SUCH_FOLDER',
id: '53326628-a00d-40a6-a3cd-8975105c0f95',
},
},
res: { res: {
type: 'object' as const, type: 'object' as const,
@ -46,9 +40,7 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (parent == null) { if (parent == null) throw new ApiError('NO_SUCH_FOLDER');
throw new ApiError(meta.errors.noSuchFolder);
}
} }
// Create folder // Create folder

View file

@ -10,19 +10,7 @@ export const meta = {
kind: 'write:drive', kind: 'write:drive',
errors: { errors: ['HAS_CHILD_FILES_OR_FOLDERS', 'NO_SUCH_FOLDER'],
noSuchFolder: {
message: 'No such folder.',
code: 'NO_SUCH_FOLDER',
id: '1069098f-c281-440f-b085-f9932edbe091',
},
hasChildFilesOrFolders: {
message: 'This folder has child files or folders.',
code: 'HAS_CHILD_FILES_OR_FOLDERS',
id: 'b0fc8a17-963c-405d-bfbc-859a487295e1',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -41,9 +29,7 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (folder == null) { if (folder == null) throw new ApiError('NO_SUCH_FOLDER');
throw new ApiError(meta.errors.noSuchFolder);
}
const [childFoldersCount, childFilesCount] = await Promise.all([ const [childFoldersCount, childFilesCount] = await Promise.all([
DriveFolders.countBy({ parentId: folder.id }), DriveFolders.countBy({ parentId: folder.id }),
@ -51,7 +37,7 @@ export default define(meta, paramDef, async (ps, user) => {
]); ]);
if (childFoldersCount !== 0 || childFilesCount !== 0) { if (childFoldersCount !== 0 || childFilesCount !== 0) {
throw new ApiError(meta.errors.hasChildFilesOrFolders); throw new ApiError('HAS_CHILD_FILES_OR_FOLDERS');
} }
await DriveFolders.delete(folder.id); await DriveFolders.delete(folder.id);

View file

@ -15,13 +15,7 @@ export const meta = {
ref: 'DriveFolder', ref: 'DriveFolder',
}, },
errors: { errors: ['NO_SUCH_FOLDER'],
noSuchFolder: {
message: 'No such folder.',
code: 'NO_SUCH_FOLDER',
id: 'd74ab9eb-bb09-4bba-bf24-fb58f761e1e9',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -40,9 +34,7 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (folder == null) { if (folder == null) throw new ApiError('NO_SUCH_FOLDER');
throw new ApiError(meta.errors.noSuchFolder);
}
return await DriveFolders.pack(folder, { return await DriveFolders.pack(folder, {
detail: true, detail: true,

View file

@ -10,25 +10,7 @@ export const meta = {
kind: 'write:drive', kind: 'write:drive',
errors: { errors: ['NO_SUCH_FOLDER', 'NO_SUCH_PARENT_FOLDER', 'RECURSIVE_FOLDER'],
noSuchFolder: {
message: 'No such folder.',
code: 'NO_SUCH_FOLDER',
id: 'f7974dac-2c0d-4a27-926e-23583b28e98e',
},
noSuchParentFolder: {
message: 'No such parent folder.',
code: 'NO_SUCH_PARENT_FOLDER',
id: 'ce104e3a-faaf-49d5-b459-10ff0cbbcaa1',
},
recursiveNesting: {
message: 'It can not be structured like nesting folders recursively.',
code: 'NO_SUCH_PARENT_FOLDER',
id: 'ce104e3a-faaf-49d5-b459-10ff0cbbcaa1',
},
},
res: { res: {
type: 'object', type: 'object',
@ -55,15 +37,13 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (folder == null) { if (folder == null) throw new ApiError('NO_SUCH_FOLDER');
throw new ApiError(meta.errors.noSuchFolder);
}
if (ps.name) folder.name = ps.name; if (ps.name) folder.name = ps.name;
if (ps.parentId !== undefined) { if (ps.parentId !== undefined) {
if (ps.parentId === folder.id) { if (ps.parentId === folder.id) {
throw new ApiError(meta.errors.recursiveNesting); throw new ApiError('RECURSIVE_FOLDER');
} else if (ps.parentId === null) { } else if (ps.parentId === null) {
folder.parentId = null; folder.parentId = null;
} else { } else {
@ -73,9 +53,7 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (parent == null) { if (parent == null) throw new ApiError('NO_SUCH_PARENT_FOLDER');
throw new ApiError(meta.errors.noSuchParentFolder);
}
// Check if the circular reference will occur // Check if the circular reference will occur
async function checkCircle(folderId: string): Promise<boolean> { async function checkCircle(folderId: string): Promise<boolean> {
@ -95,7 +73,7 @@ export default define(meta, paramDef, async (ps, user) => {
if (parent.parentId !== null) { if (parent.parentId !== null) {
if (await checkCircle(parent.parentId)) { if (await checkCircle(parent.parentId)) {
throw new ApiError(meta.errors.recursiveNesting); throw new ApiError('RECURSIVE_FOLDER');
} }
} }

View file

@ -18,37 +18,7 @@ export const meta = {
kind: 'write:following', kind: 'write:following',
errors: { errors: ['ALREADY_FOLLOWING', 'BLOCKING', 'BLOCKED', 'FOLLOWEE_IS_YOURSELF', 'NO_SUCH_USER'],
noSuchUser: {
message: 'No such user.',
code: 'NO_SUCH_USER',
id: 'fcd2eef9-a9b2-4c4f-8624-038099e90aa5',
},
followeeIsYourself: {
message: 'Followee is yourself.',
code: 'FOLLOWEE_IS_YOURSELF',
id: '26fbe7bb-a331-4857-af17-205b426669a9',
},
alreadyFollowing: {
message: 'You are already following that user.',
code: 'ALREADY_FOLLOWING',
id: '35387507-38c7-4cb9-9197-300b93783fa0',
},
blocking: {
message: 'You are blocking that user.',
code: 'BLOCKING',
id: '4e2206ec-aa4f-4960-b865-6c23ac38e2d9',
},
blocked: {
message: 'You are blocked by that user.',
code: 'BLOCKED',
id: 'c4ab57cc-4e41-45e9-bfd9-584f61e35ce0',
},
},
res: { res: {
type: 'object', type: 'object',
@ -70,13 +40,11 @@ export default define(meta, paramDef, async (ps, user) => {
const follower = user; const follower = user;
// 自分自身 // 自分自身
if (user.id === ps.userId) { if (user.id === ps.userId) throw new ApiError('FOLLOWEE_IS_YOURSELF');
throw new ApiError(meta.errors.followeeIsYourself);
}
// Get followee // Get followee
const followee = await getUser(ps.userId).catch(e => { const followee = await getUser(ps.userId).catch(e => {
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError('NO_SUCH_USER');
throw e; throw e;
}); });
@ -86,16 +54,14 @@ export default define(meta, paramDef, async (ps, user) => {
followeeId: followee.id, followeeId: followee.id,
}); });
if (exist != null) { if (exist != null) throw new ApiError('ALREADY_FOLLOWING');
throw new ApiError(meta.errors.alreadyFollowing);
}
try { try {
await create(follower, followee); await create(follower, followee);
} catch (e) { } catch (e) {
if (e instanceof IdentifiableError) { if (e instanceof IdentifiableError) {
if (e.id === '710e8fb0-b8c3-4922-be49-d5d93d8e6a6e') throw new ApiError(meta.errors.blocking); if (e.id === '710e8fb0-b8c3-4922-be49-d5d93d8e6a6e') throw new ApiError('BLOCKING');
if (e.id === '3338392a-f764-498d-8855-db939dcf8c48') throw new ApiError(meta.errors.blocked); if (e.id === '3338392a-f764-498d-8855-db939dcf8c48') throw new ApiError('BLOCKED');
} }
throw e; throw e;
} }

View file

@ -17,25 +17,7 @@ export const meta = {
kind: 'write:following', kind: 'write:following',
errors: { errors: ['FOLLOWEE_IS_YOURSELF', 'NO_SUCH_USER', 'NOT_FOLLOWING'],
noSuchUser: {
message: 'No such user.',
code: 'NO_SUCH_USER',
id: '5b12c78d-2b28-4dca-99d2-f56139b42ff8',
},
followeeIsYourself: {
message: 'Followee is yourself.',
code: 'FOLLOWEE_IS_YOURSELF',
id: 'd9e400b9-36b0-4808-b1d8-79e707f1296c',
},
notFollowing: {
message: 'You are not following that user.',
code: 'NOT_FOLLOWING',
id: '5dbf82f5-c92b-40b1-87d1-6c8c0741fd09',
},
},
res: { res: {
type: 'object', type: 'object',
@ -57,13 +39,11 @@ export default define(meta, paramDef, async (ps, user) => {
const follower = user; const follower = user;
// Check if the followee is yourself // Check if the followee is yourself
if (user.id === ps.userId) { if (user.id === ps.userId) throw new ApiError('FOLLOWEE_IS_YOURSELF');
throw new ApiError(meta.errors.followeeIsYourself);
}
// Get followee // Get followee
const followee = await getUser(ps.userId).catch(e => { const followee = await getUser(ps.userId).catch(e => {
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError('NO_SUCH_USER');
throw e; throw e;
}); });
@ -73,9 +53,7 @@ export default define(meta, paramDef, async (ps, user) => {
followeeId: followee.id, followeeId: followee.id,
}); });
if (exist == null) { if (exist == null) throw new ApiError('NOT_FOLLOWING');
throw new ApiError(meta.errors.notFollowing);
}
await deleteFollowing(follower, followee); await deleteFollowing(follower, followee);

View file

@ -17,25 +17,7 @@ export const meta = {
kind: 'write:following', kind: 'write:following',
errors: { errors: ['FOLLOWER_IS_YOURSELF', 'NO_SUCH_USER', 'NOT_FOLLOWING'],
noSuchUser: {
message: 'No such user.',
code: 'NO_SUCH_USER',
id: '5b12c78d-2b28-4dca-99d2-f56139b42ff8',
},
followerIsYourself: {
message: 'Follower is yourself.',
code: 'FOLLOWER_IS_YOURSELF',
id: '07dc03b9-03da-422d-885b-438313707662',
},
notFollowing: {
message: 'The other use is not following you.',
code: 'NOT_FOLLOWING',
id: '5dbf82f5-c92b-40b1-87d1-6c8c0741fd09',
},
},
res: { res: {
type: 'object', type: 'object',
@ -57,13 +39,11 @@ export default define(meta, paramDef, async (ps, user) => {
const followee = user; const followee = user;
// Check if the follower is yourself // Check if the follower is yourself
if (user.id === ps.userId) { if (user.id === ps.userId) throw new ApiError('FOLLOWER_IS_YOURSELF');
throw new ApiError(meta.errors.followerIsYourself);
}
// Get follower // Get follower
const follower = await getUser(ps.userId).catch(e => { const follower = await getUser(ps.userId).catch(e => {
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError('NO_SUCH_USER');
throw e; throw e;
}); });
@ -73,9 +53,7 @@ export default define(meta, paramDef, async (ps, user) => {
followeeId: followee.id, followeeId: followee.id,
}); });
if (exist == null) { if (exist == null) throw new ApiError('NOT_FOLLOWING');
throw new ApiError(meta.errors.notFollowing);
}
await deleteFollowing(follower, followee); await deleteFollowing(follower, followee);

View file

@ -10,18 +10,7 @@ export const meta = {
kind: 'write:following', kind: 'write:following',
errors: { errors: ['NO_SUCH_USER', 'NO_SUCH_FOLLOW_REQUEST'],
noSuchUser: {
message: 'No such user.',
code: 'NO_SUCH_USER',
id: '66ce1645-d66c-46bb-8b79-96739af885bd',
},
noFollowRequest: {
message: 'No follow request.',
code: 'NO_FOLLOW_REQUEST',
id: 'bcde4f8b-0913-4614-8881-614e522fb041',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -36,12 +25,12 @@ export const paramDef = {
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
// Fetch follower // Fetch follower
const follower = await getUser(ps.userId).catch(e => { const follower = await getUser(ps.userId).catch(e => {
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError('NO_SUCH_USER');
throw e; throw e;
}); });
await acceptFollowRequest(user, follower).catch(e => { await acceptFollowRequest(user, follower).catch(e => {
if (e.id === '8884c2dd-5795-4ac9-b27e-6a01d38190f9') throw new ApiError(meta.errors.noFollowRequest); if (e.id === '8884c2dd-5795-4ac9-b27e-6a01d38190f9') throw new ApiError('NO_SUCH_FOLLOW_REQUEST');
throw e; throw e;
}); });

View file

@ -12,19 +12,7 @@ export const meta = {
kind: 'write:following', kind: 'write:following',
errors: { errors: ['NO_SUCH_USER', 'NO_SUCH_FOLLOW_REQUEST'],
noSuchUser: {
message: 'No such user.',
code: 'NO_SUCH_USER',
id: '4e68c551-fc4c-4e46-bb41-7d4a37bf9dab',
},
followRequestNotFound: {
message: 'Follow request not found.',
code: 'FOLLOW_REQUEST_NOT_FOUND',
id: '089b125b-d338-482a-9a09-e2622ac9f8d4',
},
},
res: { res: {
type: 'object', type: 'object',
@ -45,7 +33,7 @@ export const paramDef = {
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
// Fetch followee // Fetch followee
const followee = await getUser(ps.userId).catch(e => { const followee = await getUser(ps.userId).catch(e => {
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError('NO_SUCH_USER');
throw e; throw e;
}); });
@ -53,7 +41,7 @@ export default define(meta, paramDef, async (ps, user) => {
await cancelFollowRequest(followee, user); await cancelFollowRequest(followee, user);
} catch (e) { } catch (e) {
if (e instanceof IdentifiableError) { if (e instanceof IdentifiableError) {
if (e.id === '17447091-ce07-46dd-b331-c1fd4f15b1e7') throw new ApiError(meta.errors.followRequestNotFound); if (e.id === '17447091-ce07-46dd-b331-c1fd4f15b1e7') throw new ApiError('NO_SUCH_FOLLOW_REQUEST');
} }
throw e; throw e;
} }

View file

@ -10,13 +10,7 @@ export const meta = {
kind: 'write:following', kind: 'write:following',
errors: { errors: ['NO_SUCH_USER'],
noSuchUser: {
message: 'No such user.',
code: 'NO_SUCH_USER',
id: 'abc2ffa6-25b2-4380-ba99-321ff3a94555',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -31,7 +25,7 @@ export const paramDef = {
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
// Fetch follower // Fetch follower
const follower = await getUser(ps.userId).catch(e => { const follower = await getUser(ps.userId).catch(e => {
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError('NO_SUCH_USER');
throw e; throw e;
}); });

View file

@ -22,10 +22,6 @@ export const meta = {
optional: false, nullable: false, optional: false, nullable: false,
ref: 'GalleryPost', ref: 'GalleryPost',
}, },
errors: {
},
} as const; } as const;
export const paramDef = { export const paramDef = {

View file

@ -9,13 +9,7 @@ export const meta = {
kind: 'write:gallery', kind: 'write:gallery',
errors: { errors: ['NO_SUCH_POST'],
noSuchPost: {
message: 'No such post.',
code: 'NO_SUCH_POST',
id: 'ae52f367-4bd7-4ecd-afc6-5672fff427f5',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -33,9 +27,7 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (post == null) { if (post == null) throw new ApiError('NO_SUCH_POST');
throw new ApiError(meta.errors.noSuchPost);
}
await GalleryPosts.delete(post.id); await GalleryPosts.delete(post.id);
}); });

View file

@ -10,19 +10,7 @@ export const meta = {
kind: 'write:gallery-likes', kind: 'write:gallery-likes',
errors: { errors: ['NO_SUCH_POST', 'ALREADY_LIKED'],
noSuchPost: {
message: 'No such post.',
code: 'NO_SUCH_POST',
id: '56c06af3-1287-442f-9701-c93f7c4a62ff',
},
alreadyLiked: {
message: 'The post has already been liked.',
code: 'ALREADY_LIKED',
id: '40e9ed56-a59c-473a-bf3f-f289c54fb5a7',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -36,9 +24,7 @@ export const paramDef = {
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
const post = await GalleryPosts.findOneBy({ id: ps.postId }); const post = await GalleryPosts.findOneBy({ id: ps.postId });
if (post == null) { if (post == null) throw new ApiError('NO_SUCH_POST');
throw new ApiError(meta.errors.noSuchPost);
}
// if already liked // if already liked
const exist = await GalleryLikes.findOneBy({ const exist = await GalleryLikes.findOneBy({
@ -46,9 +32,7 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (exist != null) { if (exist != null) throw new ApiError('ALREADY_LIKED');
throw new ApiError(meta.errors.alreadyLiked);
}
// Create like // Create like
await GalleryLikes.insert({ await GalleryLikes.insert({

View file

@ -7,13 +7,7 @@ export const meta = {
requireCredential: false, requireCredential: false,
errors: { errors: ['NO_SUCH_POST'],
noSuchPost: {
message: 'No such post.',
code: 'NO_SUCH_POST',
id: '1137bf14-c5b0-4604-85bb-5b5371b1cd45',
},
},
res: { res: {
type: 'object', type: 'object',
@ -36,9 +30,7 @@ export default define(meta, paramDef, async (ps, me) => {
id: ps.postId, id: ps.postId,
}); });
if (post == null) { if (post == null) throw new ApiError('NO_SUCH_POST');
throw new ApiError(meta.errors.noSuchPost);
}
return await GalleryPosts.pack(post, me); return await GalleryPosts.pack(post, me);
}); });

View file

@ -9,19 +9,7 @@ export const meta = {
kind: 'write:gallery-likes', kind: 'write:gallery-likes',
errors: { errors: ['NO_SUCH_POST', 'NOT_LIKED'],
noSuchPost: {
message: 'No such post.',
code: 'NO_SUCH_POST',
id: 'c32e6dd0-b555-4413-925e-b3757d19ed84',
},
notLiked: {
message: 'You have not liked that post.',
code: 'NOT_LIKED',
id: 'e3e8e06e-be37-41f7-a5b4-87a8250288f0',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -35,18 +23,14 @@ export const paramDef = {
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
const post = await GalleryPosts.findOneBy({ id: ps.postId }); const post = await GalleryPosts.findOneBy({ id: ps.postId });
if (post == null) { if (post == null) throw new ApiError('NO_SUCH_POST');
throw new ApiError(meta.errors.noSuchPost);
}
const exist = await GalleryLikes.findOneBy({ const exist = await GalleryLikes.findOneBy({
postId: post.id, postId: post.id,
userId: user.id, userId: user.id,
}); });
if (exist == null) { if (exist == null) throw new ApiError('NOT_LIKED');
throw new ApiError(meta.errors.notLiked);
}
// Delete like // Delete like
await GalleryLikes.delete(exist.id); await GalleryLikes.delete(exist.id);

View file

@ -20,10 +20,6 @@ export const meta = {
optional: false, nullable: false, optional: false, nullable: false,
ref: 'GalleryPost', ref: 'GalleryPost',
}, },
errors: {
},
} as const; } as const;
export const paramDef = { export const paramDef = {

View file

@ -14,13 +14,7 @@ export const meta = {
ref: 'Hashtag', ref: 'Hashtag',
}, },
errors: { errors: ['NO_SUCH_HASHTAG'],
noSuchHashtag: {
message: 'No such hashtag.',
code: 'NO_SUCH_HASHTAG',
id: '110ee688-193e-4a3a-9ecf-c167b2e6981e',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -34,9 +28,7 @@ export const paramDef = {
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
const hashtag = await Hashtags.findOneBy({ name: normalizeForSearch(ps.tag) }); const hashtag = await Hashtags.findOneBy({ name: normalizeForSearch(ps.tag) });
if (hashtag == null) { if (hashtag == null) throw new ApiError('NO_SUCH_HASHTAG');
throw new ApiError(meta.errors.noSuchHashtag);
}
return await Hashtags.pack(hashtag); return await Hashtags.pack(hashtag);
}); });

View file

@ -13,31 +13,7 @@ export const meta = {
max: 1, max: 1,
}, },
errors: { errors: ['EMPTY_FILE', 'FILE_TOO_BIG', 'NO_SUCH_FILE'],
noSuchFile: {
message: 'No such file.',
code: 'NO_SUCH_FILE',
id: 'ebb53e5f-6574-9c0c-0b92-7ca6def56d7e',
},
unexpectedFileType: {
message: 'We need csv file.',
code: 'UNEXPECTED_FILE_TYPE',
id: 'b6fab7d6-d945-d67c-dfdb-32da1cd12cfe',
},
tooBigFile: {
message: 'That file is too big.',
code: 'TOO_BIG_FILE',
id: 'b7fbf0b1-aeef-3b21-29ef-fadd4cb72ccf',
},
emptyFile: {
message: 'That file is empty.',
code: 'EMPTY_FILE',
id: '6f3a4dcc-f060-a707-4950-806fbdbe60d6',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -52,10 +28,9 @@ export const paramDef = {
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
const file = await DriveFiles.findOneBy({ id: ps.fileId }); const file = await DriveFiles.findOneBy({ id: ps.fileId });
if (file == null) throw new ApiError(meta.errors.noSuchFile); if (file == null) throw new ApiError('EMPTY_FILE');
//if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType); if (file.size > 50000) throw new ApiError('FILE_TOO_BIG');
if (file.size > 50000) throw new ApiError(meta.errors.tooBigFile); if (file.size === 0) throw new ApiError('EMPTY_FILE');
if (file.size === 0) throw new ApiError(meta.errors.emptyFile);
createImportBlockingJob(user, file.id); createImportBlockingJob(user, file.id);
}); });

View file

@ -12,31 +12,7 @@ export const meta = {
max: 1, max: 1,
}, },
errors: { errors: ['EMPTY_FILE', 'FILE_TOO_BIG', 'NO_SUCH_FILE'],
noSuchFile: {
message: 'No such file.',
code: 'NO_SUCH_FILE',
id: 'b98644cf-a5ac-4277-a502-0b8054a709a3',
},
unexpectedFileType: {
message: 'We need csv file.',
code: 'UNEXPECTED_FILE_TYPE',
id: '660f3599-bce0-4f95-9dde-311fd841c183',
},
tooBigFile: {
message: 'That file is too big.',
code: 'TOO_BIG_FILE',
id: 'dee9d4ed-ad07-43ed-8b34-b2856398bc60',
},
emptyFile: {
message: 'That file is empty.',
code: 'EMPTY_FILE',
id: '31a1b42c-06f7-42ae-8a38-a661c5c9f691',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -51,10 +27,9 @@ export const paramDef = {
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
const file = await DriveFiles.findOneBy({ id: ps.fileId }); const file = await DriveFiles.findOneBy({ id: ps.fileId });
if (file == null) throw new ApiError(meta.errors.noSuchFile); if (file == null) throw new ApiError('NO_SUCH_FILE');
//if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType); if (file.size > 50000) throw new ApiError('FILE_TOO_BIG');
if (file.size > 50000) throw new ApiError(meta.errors.tooBigFile); if (file.size === 0) throw new ApiError('EMPTY_FILE');
if (file.size === 0) throw new ApiError(meta.errors.emptyFile);
createImportFollowingJob(user, file.id); createImportFollowingJob(user, file.id);
}); });

View file

@ -13,31 +13,7 @@ export const meta = {
max: 1, max: 1,
}, },
errors: { errors: ['EMPTY_FILE', 'FILE_TOO_BIG', 'NO_SUCH_FILE'],
noSuchFile: {
message: 'No such file.',
code: 'NO_SUCH_FILE',
id: 'e674141e-bd2a-ba85-e616-aefb187c9c2a',
},
unexpectedFileType: {
message: 'We need csv file.',
code: 'UNEXPECTED_FILE_TYPE',
id: '568c6e42-c86c-ba09-c004-517f83f9f1a8',
},
tooBigFile: {
message: 'That file is too big.',
code: 'TOO_BIG_FILE',
id: '9b4ada6d-d7f7-0472-0713-4f558bd1ec9c',
},
emptyFile: {
message: 'That file is empty.',
code: 'EMPTY_FILE',
id: 'd2f12af1-e7b4-feac-86a3-519548f2728e',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -52,10 +28,9 @@ export const paramDef = {
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
const file = await DriveFiles.findOneBy({ id: ps.fileId }); const file = await DriveFiles.findOneBy({ id: ps.fileId });
if (file == null) throw new ApiError(meta.errors.noSuchFile); if (file == null) throw new ApiError('NO_SUCH_FILE');
//if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType); if (file.size > 50000) throw new ApiError('FILE_TOO_BIG');
if (file.size > 50000) throw new ApiError(meta.errors.tooBigFile); if (file.size === 0) throw new ApiError('EMPTY_FILE');
if (file.size === 0) throw new ApiError(meta.errors.emptyFile);
createImportMutingJob(user, file.id); createImportMutingJob(user, file.id);
}); });

View file

@ -12,31 +12,7 @@ export const meta = {
max: 1, max: 1,
}, },
errors: { errors: ['EMPTY_FILE', 'FILE_TOO_BIG', 'NO_SUCH_FILE'],
noSuchFile: {
message: 'No such file.',
code: 'NO_SUCH_FILE',
id: 'ea9cc34f-c415-4bc6-a6fe-28ac40357049',
},
unexpectedFileType: {
message: 'We need csv file.',
code: 'UNEXPECTED_FILE_TYPE',
id: 'a3c9edda-dd9b-4596-be6a-150ef813745c',
},
tooBigFile: {
message: 'That file is too big.',
code: 'TOO_BIG_FILE',
id: 'ae6e7a22-971b-4b52-b2be-fc0b9b121fe9',
},
emptyFile: {
message: 'That file is empty.',
code: 'EMPTY_FILE',
id: '99efe367-ce6e-4d44-93f8-5fae7b040356',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -51,10 +27,9 @@ export const paramDef = {
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
const file = await DriveFiles.findOneBy({ id: ps.fileId }); const file = await DriveFiles.findOneBy({ id: ps.fileId });
if (file == null) throw new ApiError(meta.errors.noSuchFile); if (file == null) throw new ApiError('NO_SUCH_FILE');
//if (!file.type.endsWith('/csv')) throw new ApiError(meta.errors.unexpectedFileType); if (file.size > 30000) throw new ApiError('FILE_TOO_BIG');
if (file.size > 30000) throw new ApiError(meta.errors.tooBigFile); if (file.size === 0) throw new ApiError('EMPTY_FILE');
if (file.size === 0) throw new ApiError(meta.errors.emptyFile);
createImportUserListsJob(user, file.id); createImportUserListsJob(user, file.id);
}); });

View file

@ -10,25 +10,7 @@ export const meta = {
kind: 'write:account', kind: 'write:account',
errors: { errors: ['ALREADY_PINNED', 'NO_SUCH_NOTE', 'PIN_LIMIT_EXCEEDED'],
noSuchNote: {
message: 'No such note.',
code: 'NO_SUCH_NOTE',
id: '56734f8b-3928-431e-bf80-6ff87df40cb3',
},
pinLimitExceeded: {
message: 'You can not pin notes any more.',
code: 'PIN_LIMIT_EXCEEDED',
id: '72dab508-c64d-498f-8740-a8eec1ba385a',
},
alreadyPinned: {
message: 'That note has already been pinned.',
code: 'ALREADY_PINNED',
id: '8b18c2b7-68fe-4edb-9892-c0cbaeb6c913',
},
},
res: { res: {
type: 'object', type: 'object',
@ -48,9 +30,9 @@ export const paramDef = {
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
await addPinned(user, ps.noteId).catch(e => { await addPinned(user, ps.noteId).catch(e => {
if (e.id === '70c4e51f-5bea-449c-a030-53bee3cce202') throw new ApiError(meta.errors.noSuchNote); if (e.id === '70c4e51f-5bea-449c-a030-53bee3cce202') throw new ApiError('NO_SUCH_NOTE');
if (e.id === '15a018eb-58e5-4da1-93be-330fcc5e4e1a') throw new ApiError(meta.errors.pinLimitExceeded); if (e.id === '15a018eb-58e5-4da1-93be-330fcc5e4e1a') throw new ApiError('PIN_LIMIT_EXCEEDED');
if (e.id === '23f0cf4e-59a3-4276-a91d-61a5891c1514') throw new ApiError(meta.errors.alreadyPinned); if (e.id === '23f0cf4e-59a3-4276-a91d-61a5891c1514') throw new ApiError('ALREADY_PINNED');
throw e; throw e;
}); });

View file

@ -11,13 +11,7 @@ export const meta = {
kind: 'write:account', kind: 'write:account',
errors: { errors: ['NO_SUCH_ANNOUNCEMENT'],
noSuchAnnouncement: {
message: 'No such announcement.',
code: 'NO_SUCH_ANNOUNCEMENT',
id: '184663db-df88-4bc2-8b52-fb85f0681939',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -33,9 +27,7 @@ export default define(meta, paramDef, async (ps, user) => {
// Check if announcement exists // Check if announcement exists
const announcement = await Announcements.findOneBy({ id: ps.announcementId }); const announcement = await Announcements.findOneBy({ id: ps.announcementId });
if (announcement == null) { if (announcement == null) throw new ApiError('NO_SUCH_ANNOUNCEMENT');
throw new ApiError(meta.errors.noSuchAnnouncement);
}
// Check if already read // Check if already read
const read = await AnnouncementReads.findOneBy({ const read = await AnnouncementReads.findOneBy({
@ -43,9 +35,7 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (read != null) { if (read != null) return;
return;
}
// Create read // Create read
await AnnouncementReads.insert({ await AnnouncementReads.insert({

View file

@ -7,13 +7,7 @@ export const meta = {
secure: true, secure: true,
errors: { errors: ['NO_SUCH_KEY'],
noSuchKey: {
message: 'No such key.',
code: 'NO_SUCH_KEY',
id: '97a1e8e7-c0f7-47d2-957a-92e61256e01a',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -37,9 +31,7 @@ export default define(meta, paramDef, async (ps, user) => {
const item = await query.getOne(); const item = await query.getOne();
if (item == null) { if (item == null) throw new ApiError('NO_SUCH_KEY');
throw new ApiError(meta.errors.noSuchKey);
}
return { return {
updatedAt: item.updatedAt, updatedAt: item.updatedAt,

View file

@ -7,13 +7,7 @@ export const meta = {
secure: true, secure: true,
errors: { errors: ['NO_SUCH_KEY'],
noSuchKey: {
message: 'No such key.',
code: 'NO_SUCH_KEY',
id: 'ac3ed68a-62f0-422b-a7bc-d5e09e8f6a6a',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -37,9 +31,7 @@ export default define(meta, paramDef, async (ps, user) => {
const item = await query.getOne(); const item = await query.getOne();
if (item == null) { if (item == null) throw new ApiError('NO_SUCH_KEY');
throw new ApiError(meta.errors.noSuchKey);
}
return item.value; return item.value;
}); });

View file

@ -7,13 +7,7 @@ export const meta = {
secure: true, secure: true,
errors: { errors: ['NO_SUCH_KEY'],
noSuchKey: {
message: 'No such key.',
code: 'NO_SUCH_KEY',
id: '1fac4e8a-a6cd-4e39-a4a5-3a7e11f1b019',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -37,9 +31,7 @@ export default define(meta, paramDef, async (ps, user) => {
const item = await query.getOne(); const item = await query.getOne();
if (item == null) { if (item == null) throw new ApiError('NO_SUCH_KEY');
throw new ApiError(meta.errors.noSuchKey);
}
await RegistryItems.remove(item); await RegistryItems.remove(item);
}); });

View file

@ -10,13 +10,7 @@ export const meta = {
kind: 'write:account', kind: 'write:account',
errors: { errors: ['NO_SUCH_NOTE'],
noSuchNote: {
message: 'No such note.',
code: 'NO_SUCH_NOTE',
id: '454170ce-9d63-4a43-9da1-ea10afe81e21',
},
},
res: { res: {
type: 'object', type: 'object',
@ -36,7 +30,7 @@ export const paramDef = {
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
await removePinned(user, ps.noteId).catch(e => { await removePinned(user, ps.noteId).catch(e => {
if (e.id === 'b302d4cf-c050-400a-bbb3-be208681f40c') throw new ApiError(meta.errors.noSuchNote); if (e.id === 'b302d4cf-c050-400a-bbb3-be208681f40c') throw new ApiError('NO_SUCH_NOTE');
throw e; throw e;
}); });

View file

@ -19,19 +19,9 @@ export const meta = {
max: 3, max: 3,
}, },
errors: { // FIXME: refactor to remove both of these errors?
incorrectPassword: { // the password should not be passed as it is not compatible with using OAuth
message: 'Incorrect password.', errors: ['ACCESS_DENIED', 'INTERNAL_ERROR'],
code: 'INCORRECT_PASSWORD',
id: 'e54c1d7e-e7d6-4103-86b6-0a95069b4ad3',
},
unavailable: {
message: 'Unavailable email address.',
code: 'UNAVAILABLE',
id: 'a2defefb-f220-8849-0af6-17f816099323',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -50,15 +40,11 @@ export default define(meta, paramDef, async (ps, user) => {
// Compare password // Compare password
const same = await bcrypt.compare(ps.password, profile.password!); const same = await bcrypt.compare(ps.password, profile.password!);
if (!same) { if (!same) throw new ApiError('ACCESS_DENIED');
throw new ApiError(meta.errors.incorrectPassword);
}
if (ps.email != null) { if (ps.email != null) {
const available = await validateEmailForAccount(ps.email); const available = await validateEmailForAccount(ps.email);
if (!available) { if (!available) throw new ApiError('INTERNAL_ERROR');
throw new ApiError(meta.errors.unavailable);
}
} }
await UserProfiles.update(user.id, { await UserProfiles.update(user.id, {

View file

@ -22,43 +22,7 @@ export const meta = {
kind: 'write:account', kind: 'write:account',
errors: { errors: ['INVALID_REGEXP', 'NO_SUCH_FILE', 'NO_SUCH_PAGE', 'NOT_AN_IMAGE'],
noSuchAvatar: {
message: 'No such avatar file.',
code: 'NO_SUCH_AVATAR',
id: '539f3a45-f215-4f81-a9a8-31293640207f',
},
noSuchBanner: {
message: 'No such banner file.',
code: 'NO_SUCH_BANNER',
id: '0d8f5629-f210-41c2-9433-735831a58595',
},
avatarNotAnImage: {
message: 'The file specified as an avatar is not an image.',
code: 'AVATAR_NOT_AN_IMAGE',
id: 'f419f9f8-2f4d-46b1-9fb4-49d3a2fd7191',
},
bannerNotAnImage: {
message: 'The file specified as a banner is not an image.',
code: 'BANNER_NOT_AN_IMAGE',
id: '75aedb19-2afd-4e6d-87fc-67941256fa60',
},
noSuchPage: {
message: 'No such page.',
code: 'NO_SUCH_PAGE',
id: '8e01b590-7eb9-431b-a239-860e086c408e',
},
invalidRegexp: {
message: 'Invalid Regular Expression.',
code: 'INVALID_REGEXP',
id: '0d786918-10df-41cd-8f33-8dec7d9a89a5',
},
},
res: { res: {
type: 'object', type: 'object',
@ -142,12 +106,12 @@ export default define(meta, paramDef, async (ps, _user, token) => {
// validate regular expression syntax // validate regular expression syntax
ps.mutedWords.filter(x => !Array.isArray(x)).forEach(x => { ps.mutedWords.filter(x => !Array.isArray(x)).forEach(x => {
const regexp = x.match(/^\/(.+)\/(.*)$/); const regexp = x.match(/^\/(.+)\/(.*)$/);
if (!regexp) throw new ApiError(meta.errors.invalidRegexp); if (!regexp) throw new ApiError('INVALID_REGEXP');
try { try {
new RE2(regexp[1], regexp[2]); new RE2(regexp[1], regexp[2]);
} catch (err) { } catch (err) {
throw new ApiError(meta.errors.invalidRegexp); throw new ApiError('INVALID_REGEXP');
} }
}); });
@ -174,21 +138,21 @@ export default define(meta, paramDef, async (ps, _user, token) => {
if (ps.avatarId) { if (ps.avatarId) {
const avatar = await DriveFiles.findOneBy({ id: ps.avatarId }); const avatar = await DriveFiles.findOneBy({ id: ps.avatarId });
if (avatar == null || avatar.userId !== user.id) throw new ApiError(meta.errors.noSuchAvatar); if (avatar == null || avatar.userId !== user.id) throw new ApiError('NO_SUCH_FILE', 'Avatar file not found.');
if (!avatar.type.startsWith('image/')) throw new ApiError(meta.errors.avatarNotAnImage); if (!avatar.type.startsWith('image/')) throw new ApiError('NOT_AN_IMAGE', 'Avatar file is not an image.');
} }
if (ps.bannerId) { if (ps.bannerId) {
const banner = await DriveFiles.findOneBy({ id: ps.bannerId }); const banner = await DriveFiles.findOneBy({ id: ps.bannerId });
if (banner == null || banner.userId !== user.id) throw new ApiError(meta.errors.noSuchBanner); if (banner == null || banner.userId !== user.id) throw new ApiError('NO_SUCH_FILE', 'Banner file not found.');
if (!banner.type.startsWith('image/')) throw new ApiError(meta.errors.bannerNotAnImage); if (!banner.type.startsWith('image/')) throw new ApiError('BANNER_NOT_AN_IMAGE', 'Banner file is not an image.');
} }
if (ps.pinnedPageId) { if (ps.pinnedPageId) {
const page = await Pages.findOneBy({ id: ps.pinnedPageId }); const page = await Pages.findOneBy({ id: ps.pinnedPageId });
if (page == null || page.userId !== user.id) throw new ApiError(meta.errors.noSuchPage); if (page == null || page.userId !== user.id) throw new ApiError('NO_SUCH_PAGE');
profileUpdates.pinnedPageId = page.id; profileUpdates.pinnedPageId = page.id;
} else if (ps.pinnedPageId === null) { } else if (ps.pinnedPageId === null) {

View file

@ -10,13 +10,7 @@ export const meta = {
kind: 'write:account', kind: 'write:account',
errors: { errors: ['NO_SUCH_WEBHOOK'],
noSuchWebhook: {
message: 'No such webhook.',
code: 'NO_SUCH_WEBHOOK',
id: 'bae73e5a-5522-4965-ae19-3a8688e71d82',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -34,9 +28,7 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (webhook == null) { if (webhook == null) throw new ApiError('NO_SUCH_WEBHOOK');
throw new ApiError(meta.errors.noSuchWebhook);
}
await Webhooks.delete(webhook.id); await Webhooks.delete(webhook.id);

View file

@ -9,13 +9,7 @@ export const meta = {
kind: 'read:account', kind: 'read:account',
errors: { errors: ['NO_SUCH_WEBHOOK'],
noSuchWebhook: {
message: 'No such webhook.',
code: 'NO_SUCH_WEBHOOK',
id: '50f614d9-3047-4f7e-90d8-ad6b2d5fb098',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -33,9 +27,7 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (webhook == null) { if (webhook == null) throw new ApiError('NO_SUCH_WEBHOOK');
throw new ApiError(meta.errors.noSuchWebhook);
}
return webhook; return webhook;
}); });

View file

@ -11,14 +11,7 @@ export const meta = {
kind: 'write:account', kind: 'write:account',
errors: { errors: ['NO_SUCH_WEBHOOK'],
noSuchWebhook: {
message: 'No such webhook.',
code: 'NO_SUCH_WEBHOOK',
id: 'fb0fea69-da18-45b1-828d-bd4fd1612518',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -43,9 +36,7 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (webhook == null) { if (webhook == null) throw new ApiError('NO_SUCH_WEBHOOK');
throw new ApiError(meta.errors.noSuchWebhook);
}
await Webhooks.update(webhook.id, { await Webhooks.update(webhook.id, {
name: ps.name, name: ps.name,

View file

@ -23,25 +23,7 @@ export const meta = {
}, },
}, },
errors: { errors: ['ACCESS_DENIED', 'NO_SUCH_USER', 'NO_SUCH_GROUP'],
noSuchUser: {
message: 'No such user.',
code: 'NO_SUCH_USER',
id: '11795c64-40ea-4198-b06e-3c873ed9039d',
},
noSuchGroup: {
message: 'No such group.',
code: 'NO_SUCH_GROUP',
id: 'c4d9f88c-9270-4632-b032-6ed8cee36f7f',
},
groupAccessDenied: {
message: 'You can not read messages of groups that you have not joined.',
code: 'GROUP_ACCESS_DENIED',
id: 'a053a8dd-a491-4718-8f87-50775aad9284',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -73,7 +55,7 @@ export default define(meta, paramDef, async (ps, user) => {
if (ps.userId != null) { if (ps.userId != null) {
// Fetch recipient (user) // Fetch recipient (user)
const recipient = await getUser(ps.userId).catch(e => { const recipient = await getUser(ps.userId).catch(e => {
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError('NO_SUCH_USER');
throw e; throw e;
}); });
@ -110,9 +92,7 @@ export default define(meta, paramDef, async (ps, user) => {
// Fetch recipient (group) // Fetch recipient (group)
const recipientGroup = await UserGroups.findOneBy({ id: ps.groupId }); const recipientGroup = await UserGroups.findOneBy({ id: ps.groupId });
if (recipientGroup == null) { if (recipientGroup == null) throw new ApiError('NO_SUCH_GROUP');
throw new ApiError(meta.errors.noSuchGroup);
}
// check joined // check joined
const joining = await UserGroupJoinings.findOneBy({ const joining = await UserGroupJoinings.findOneBy({
@ -120,9 +100,7 @@ export default define(meta, paramDef, async (ps, user) => {
userGroupId: recipientGroup.id, userGroupId: recipientGroup.id,
}); });
if (joining == null) { if (joining == null) throw new ApiError('ACCESS_DENIED', 'You have to join a group to read messages in it.');
throw new ApiError(meta.errors.groupAccessDenied);
}
const query = makePaginationQuery(MessagingMessages.createQueryBuilder('message'), ps.sinceId, ps.untilId) const query = makePaginationQuery(MessagingMessages.createQueryBuilder('message'), ps.sinceId, ps.untilId)
.andWhere('message.groupId = :groupId', { groupId: recipientGroup.id }); .andWhere('message.groupId = :groupId', { groupId: recipientGroup.id });

View file

@ -19,51 +19,11 @@ export const meta = {
ref: 'MessagingMessage', ref: 'MessagingMessage',
}, },
errors: { errors: ['ACCESS_DENIED', 'BLOCKED', 'NO_SUCH_FILE', 'NO_SUCH_USER', 'NO_SUCH_GROUP', 'RECIPIENT_IS_YOURSELF'],
recipientIsYourself: {
message: 'You can not send a message to yourself.',
code: 'RECIPIENT_IS_YOURSELF',
id: '17e2ba79-e22a-4cbc-bf91-d327643f4a7e',
},
noSuchUser: {
message: 'No such user.',
code: 'NO_SUCH_USER',
id: '11795c64-40ea-4198-b06e-3c873ed9039d',
},
noSuchGroup: {
message: 'No such group.',
code: 'NO_SUCH_GROUP',
id: 'c94e2a5d-06aa-4914-8fa6-6a42e73d6537',
},
groupAccessDenied: {
message: 'You can not send messages to groups that you have not joined.',
code: 'GROUP_ACCESS_DENIED',
id: 'd96b3cca-5ad1-438b-ad8b-02f931308fbd',
},
noSuchFile: {
message: 'No such file.',
code: 'NO_SUCH_FILE',
id: '4372b8e2-185d-4146-8749-2f68864a3e5f',
},
youHaveBeenBlocked: {
message: 'You cannot send a message because you have been blocked by this user.',
code: 'YOU_HAVE_BEEN_BLOCKED',
id: 'c15a5199-7422-4968-941a-2a462c478f7d',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
type: 'object', type: 'object',
properties: {
text: { type: 'string', nullable: true, maxLength: 3000 },
fileId: { type: 'string', format: 'misskey:id' },
},
anyOf: [ anyOf: [
{ {
properties: { properties: {
@ -137,13 +97,11 @@ export default define(meta, paramDef, async (ps, user) => {
if (ps.userId != null) { if (ps.userId != null) {
// Myself // Myself
if (ps.userId === user.id) { if (ps.userId === user.id) throw new ApiError('RECIPIENT_IS_YOURSELF');
throw new ApiError(meta.errors.recipientIsYourself);
}
// Fetch recipient (user) // Fetch recipient (user)
recipientUser = await getUser(ps.userId).catch(e => { recipientUser = await getUser(ps.userId).catch(e => {
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError('NO_SUCH_USER');
throw e; throw e;
}); });
@ -152,16 +110,12 @@ export default define(meta, paramDef, async (ps, user) => {
blockerId: recipientUser.id, blockerId: recipientUser.id,
blockeeId: user.id, blockeeId: user.id,
}); });
if (block) { if (block) throw new ApiError('BLOCKED');
throw new ApiError(meta.errors.youHaveBeenBlocked);
}
} else if (ps.groupId != null) { } else if (ps.groupId != null) {
// Fetch recipient (group) // Fetch recipient (group)
recipientGroup = await UserGroups.findOneBy({ id: ps.groupId! }); recipientGroup = await UserGroups.findOneBy({ id: ps.groupId! });
if (recipientGroup == null) { if (recipientGroup == null) throw new ApiError('NO_SUCH_GROUP');
throw new ApiError(meta.errors.noSuchGroup);
}
// check joined // check joined
const joining = await UserGroupJoinings.findOneBy({ const joining = await UserGroupJoinings.findOneBy({
@ -169,9 +123,7 @@ export default define(meta, paramDef, async (ps, user) => {
userGroupId: recipientGroup.id, userGroupId: recipientGroup.id,
}); });
if (joining == null) { if (joining == null) throw new ApiError('ACCESS_DENIED', 'You have to join a group to send a message in it.');
throw new ApiError(meta.errors.groupAccessDenied);
}
} }
let file = null; let file = null;
@ -181,9 +133,7 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (file == null) { if (file == null) throw new ApiError('NO_SUCH_FILE');
throw new ApiError(meta.errors.noSuchFile);
}
} }
return await createMessage(user, recipientUser, recipientGroup, ps.text, file); return await createMessage(user, recipientUser, recipientGroup, ps.text, file);

View file

@ -17,13 +17,7 @@ export const meta = {
minInterval: SECOND, minInterval: SECOND,
}, },
errors: { errors: ['NO_SUCH_MESSAGE'],
noSuchMessage: {
message: 'No such message.',
code: 'NO_SUCH_MESSAGE',
id: '54b5b326-7925-42cf-8019-130fda8b56af',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -41,9 +35,7 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (message == null) { if (message == null) throw new ApiError('NO_SUCH_MESSAGE');
throw new ApiError(meta.errors.noSuchMessage);
}
await deleteMessage(message); await deleteMessage(message);
}); });

View file

@ -10,13 +10,7 @@ export const meta = {
kind: 'write:messaging', kind: 'write:messaging',
errors: { errors: ['NO_SUCH_MESSAGE'],
noSuchMessage: {
message: 'No such message.',
code: 'NO_SUCH_MESSAGE',
id: '86d56a2f-a9c3-4afb-b13c-3e9bfef9aa14',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -31,18 +25,16 @@ export const paramDef = {
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
const message = await MessagingMessages.findOneBy({ id: ps.messageId }); const message = await MessagingMessages.findOneBy({ id: ps.messageId });
if (message == null) { if (message == null) throw new ApiError('NO_SUCH_MESSAGE');
throw new ApiError(meta.errors.noSuchMessage);
}
if (message.recipientId) { if (message.recipientId) {
await readUserMessagingMessage(user.id, message.userId, [message.id]).catch(e => { await readUserMessagingMessage(user.id, message.userId, [message.id]).catch(e => {
if (e.id === 'e140a4bf-49ce-4fb6-b67c-b78dadf6b52f') throw new ApiError(meta.errors.noSuchMessage); if (e.id === 'e140a4bf-49ce-4fb6-b67c-b78dadf6b52f') throw new ApiError('NO_SUCH_MESSAGE');
throw e; throw e;
}); });
} else if (message.groupId) { } else if (message.groupId) {
await readGroupMessagingMessage(user.id, message.groupId, [message.id]).catch(e => { await readGroupMessagingMessage(user.id, message.groupId, [message.id]).catch(e => {
if (e.id === '930a270c-714a-46b2-b776-ad27276dc569') throw new ApiError(meta.errors.noSuchMessage); if (e.id === '930a270c-714a-46b2-b776-ad27276dc569') throw new ApiError('NO_SUCH_MESSAGE');
throw e; throw e;
}); });
} }

View file

@ -13,25 +13,7 @@ export const meta = {
kind: 'write:mutes', kind: 'write:mutes',
errors: { errors: ['NO_SUCH_USER', 'MUTEE_IS_YOURSELF', 'ALREADY_MUTING'],
noSuchUser: {
message: 'No such user.',
code: 'NO_SUCH_USER',
id: '6fef56f3-e765-4957-88e5-c6f65329b8a5',
},
muteeIsYourself: {
message: 'Mutee is yourself.',
code: 'MUTEE_IS_YOURSELF',
id: 'a4619cb2-5f23-484b-9301-94c903074e10',
},
alreadyMuting: {
message: 'You are already muting that user.',
code: 'ALREADY_MUTING',
id: '7e7359cb-160c-4956-b08f-4d1c653cd007',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -52,13 +34,11 @@ export default define(meta, paramDef, async (ps, user) => {
const muter = user; const muter = user;
// 自分自身 // 自分自身
if (user.id === ps.userId) { if (user.id === ps.userId) throw new ApiError('MUTEE_IS_YOURSELF');
throw new ApiError(meta.errors.muteeIsYourself);
}
// Get mutee // Get mutee
const mutee = await getUser(ps.userId).catch(e => { const mutee = await getUser(ps.userId).catch(e => {
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError('NO_SUCH_USER');
throw e; throw e;
}); });
@ -68,9 +48,7 @@ export default define(meta, paramDef, async (ps, user) => {
muteeId: mutee.id, muteeId: mutee.id,
}); });
if (exist != null) { if (exist != null) throw new ApiError('ALREADY_MUTING');
throw new ApiError(meta.errors.alreadyMuting);
}
if (ps.expiresAt && ps.expiresAt <= Date.now()) { if (ps.expiresAt && ps.expiresAt <= Date.now()) {
return; return;

View file

@ -11,25 +11,7 @@ export const meta = {
kind: 'write:mutes', kind: 'write:mutes',
errors: { errors: ['NO_SUCH_USER', 'MUTEE_IS_YOURSELF', 'NOT_MUTING'],
noSuchUser: {
message: 'No such user.',
code: 'NO_SUCH_USER',
id: 'b851d00b-8ab1-4a56-8b1b-e24187cb48ef',
},
muteeIsYourself: {
message: 'Mutee is yourself.',
code: 'MUTEE_IS_YOURSELF',
id: 'f428b029-6b39-4d48-a1d2-cc1ae6dd5cf9',
},
notMuting: {
message: 'You are not muting that user.',
code: 'NOT_MUTING',
id: '5467d020-daa9-4553-81e1-135c0c35a96d',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -45,13 +27,11 @@ export default define(meta, paramDef, async (ps, user) => {
const muter = user; const muter = user;
// Check if the mutee is yourself // Check if the mutee is yourself
if (user.id === ps.userId) { if (user.id === ps.userId) throw new ApiError('MUTEE_IS_YOURSELF');
throw new ApiError(meta.errors.muteeIsYourself);
}
// Get mutee // Get mutee
const mutee = await getUser(ps.userId).catch(e => { const mutee = await getUser(ps.userId).catch(e => {
if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError(meta.errors.noSuchUser); if (e.id === '15348ddd-432d-49c2-8a5a-8069753becff') throw new ApiError('NO_SUCH_USER');
throw e; throw e;
}); });
@ -61,9 +41,7 @@ export default define(meta, paramDef, async (ps, user) => {
muteeId: mutee.id, muteeId: mutee.id,
}); });
if (exist == null) { if (exist == null) throw new ApiError('NOT_MUTING');
throw new ApiError(meta.errors.notMuting);
}
// Delete mute // Delete mute
await Mutings.delete({ await Mutings.delete({

View file

@ -19,13 +19,7 @@ export const meta = {
}, },
}, },
errors: { errors: ['NO_SUCH_NOTE'],
noSuchNote: {
message: 'No such note.',
code: 'NO_SUCH_NOTE',
id: '47db1a1c-b0af-458d-8fb4-986e4efafe1e',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -39,7 +33,7 @@ export const paramDef = {
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, me) => { export default define(meta, paramDef, async (ps, me) => {
const note = await getNote(ps.noteId, me).catch(err => { const note = await getNote(ps.noteId, me).catch(err => {
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
throw err; throw err;
}); });

View file

@ -19,13 +19,7 @@ export const meta = {
}, },
}, },
errors: { errors: ['NO_SUCH_NOTE'],
noSuchNote: {
message: 'No such note.',
code: 'NO_SUCH_NOTE',
id: 'e1035875-9551-45ec-afa8-1ded1fcb53c8',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -41,7 +35,7 @@ export const paramDef = {
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
const note = await getNote(ps.noteId, user).catch(err => { const note = await getNote(ps.noteId, user).catch(err => {
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
throw err; throw err;
}); });

View file

@ -37,55 +37,7 @@ export const meta = {
}, },
}, },
errors: { errors: ['NO_SUCH_NOTE', 'PURE_RENOTE', 'EXPIRED_POLL', 'NO_SUCH_CHANNEL', 'BLOCKED', 'LESS_RESTRICTIVE_VISIBILITY'],
noSuchRenoteTarget: {
message: 'No such renote target.',
code: 'NO_SUCH_RENOTE_TARGET',
id: 'b5c90186-4ab0-49c8-9bba-a1f76c282ba4',
},
cannotReRenote: {
message: 'You can not Renote a pure Renote.',
code: 'CANNOT_RENOTE_TO_A_PURE_RENOTE',
id: 'fd4cc33e-2a37-48dd-99cc-9b806eb2031a',
},
noSuchReplyTarget: {
message: 'No such reply target.',
code: 'NO_SUCH_REPLY_TARGET',
id: '749ee0f6-d3da-459a-bf02-282e2da4292c',
},
cannotReplyToPureRenote: {
message: 'You can not reply to a pure Renote.',
code: 'CANNOT_REPLY_TO_A_PURE_RENOTE',
id: '3ac74a84-8fd5-4bb0-870f-01804f82ce15',
},
cannotCreateAlreadyExpiredPoll: {
message: 'Poll is already expired.',
code: 'CANNOT_CREATE_ALREADY_EXPIRED_POLL',
id: '04da457d-b083-4055-9082-955525eda5a5',
},
noSuchChannel: {
message: 'No such channel.',
code: 'NO_SUCH_CHANNEL',
id: 'b1653923-5453-4edc-b786-7c4f39bb0bbb',
},
youHaveBeenBlocked: {
message: 'You have been blocked by this user.',
code: 'YOU_HAVE_BEEN_BLOCKED',
id: 'b390d7e1-8a5e-46ed-b625-06271cafd3d3',
},
lessRestrictiveVisibility: {
message: 'The visibility cannot be less restrictive than the parent note.',
code: 'LESS_RESTRICTIVE_VISIBILITY',
id: 'c8ab7a7a-8852-41e2-8b24-079bbaceb585',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -199,17 +151,15 @@ export default define(meta, paramDef, async (ps, user) => {
if (ps.renoteId != null) { if (ps.renoteId != null) {
// Fetch renote to note // Fetch renote to note
renote = await getNote(ps.renoteId, user).catch(e => { renote = await getNote(ps.renoteId, user).catch(e => {
if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchRenoteTarget); if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE', 'Note to be renoted not found.');
throw e; throw e;
}); });
if (isPureRenote(renote)) { if (isPureRenote(renote)) throw new ApiError('PURE_RENOTE', 'Cannot renote a pure renote.');
throw new ApiError(meta.errors.cannotReRenote);
}
// check that the visibility is not less restrictive // check that the visibility is not less restrictive
if (noteVisibilities.indexOf(renote.visibility) > noteVisibilities.indexOf(ps.visibility)) { if (noteVisibilities.indexOf(renote.visibility) > noteVisibilities.indexOf(ps.visibility)) {
throw new ApiError(meta.errors.lessRestrictiveVisibility); throw new ApiError('LESS_RESTRICTIVE_VISIBILITY', `The renote has visibility ${renote.visibility}.`);
} }
// Check blocking // Check blocking
@ -218,9 +168,7 @@ export default define(meta, paramDef, async (ps, user) => {
blockerId: renote.userId, blockerId: renote.userId,
blockeeId: user.id, blockeeId: user.id,
}); });
if (block) { if (block) throw new ApiError('BLOCKED', 'Blocked by author of note to be renoted.');
throw new ApiError(meta.errors.youHaveBeenBlocked);
}
} }
} }
@ -228,17 +176,15 @@ export default define(meta, paramDef, async (ps, user) => {
if (ps.replyId != null) { if (ps.replyId != null) {
// Fetch reply // Fetch reply
reply = await getNote(ps.replyId, user).catch(e => { reply = await getNote(ps.replyId, user).catch(e => {
if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchReplyTarget); if (e.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE', 'Replied to note not found.');
throw e; throw e;
}); });
if (isPureRenote(reply)) { if (isPureRenote(reply)) throw new ApiError('PURE_RENOTE', 'Cannot reply to a pure renote.');
throw new ApiError(meta.errors.cannotReplyToPureRenote);
}
// check that the visibility is not less restrictive // check that the visibility is not less restrictive
if (noteVisibilities.indexOf(reply.visibility) > noteVisibilities.indexOf(ps.visibility)) { if (noteVisibilities.indexOf(reply.visibility) > noteVisibilities.indexOf(ps.visibility)) {
throw new ApiError(meta.errors.lessRestrictiveVisibility); throw new ApiError('LESS_RESTRICTIVE_VISIBILITY', `The replied to note has visibility ${reply.visibility}.`);
} }
// Check blocking // Check blocking
@ -247,16 +193,14 @@ export default define(meta, paramDef, async (ps, user) => {
blockerId: reply.userId, blockerId: reply.userId,
blockeeId: user.id, blockeeId: user.id,
}); });
if (block) { if (block) throw new ApiError('BLOCKED', 'Blocked by author of replied to note.');
throw new ApiError(meta.errors.youHaveBeenBlocked);
}
} }
} }
if (ps.poll) { if (ps.poll) {
if (typeof ps.poll.expiresAt === 'number') { if (typeof ps.poll.expiresAt === 'number') {
if (ps.poll.expiresAt < Date.now()) { if (ps.poll.expiresAt < Date.now()) {
throw new ApiError(meta.errors.cannotCreateAlreadyExpiredPoll); throw new ApiError('EXPIRED_POLL');
} }
} else if (typeof ps.poll.expiredAfter === 'number') { } else if (typeof ps.poll.expiredAfter === 'number') {
ps.poll.expiresAt = Date.now() + ps.poll.expiredAfter; ps.poll.expiresAt = Date.now() + ps.poll.expiredAfter;
@ -267,9 +211,7 @@ export default define(meta, paramDef, async (ps, user) => {
if (ps.channelId != null) { if (ps.channelId != null) {
channel = await Channels.findOneBy({ id: ps.channelId }); channel = await Channels.findOneBy({ id: ps.channelId });
if (channel == null) { if (channel == null) throw new ApiError('NO_SUCH_CHANNEL');
throw new ApiError(meta.errors.noSuchChannel);
}
} }
// 投稿を作成 // 投稿を作成

View file

@ -18,19 +18,7 @@ export const meta = {
minInterval: SECOND, minInterval: SECOND,
}, },
errors: { errors: ['ACCESS_DENIED', 'NO_SUCH_NOTE'],
noSuchNote: {
message: 'No such note.',
code: 'NO_SUCH_NOTE',
id: '490be23f-8c1f-4796-819f-94cb4f9d1630',
},
accessDenied: {
message: 'Access denied.',
code: 'ACCESS_DENIED',
id: 'fe8d7103-0ea8-4ec3-814d-f8b401dc69e9',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -44,12 +32,12 @@ export const paramDef = {
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
const note = await getNote(ps.noteId, user).catch(err => { const note = await getNote(ps.noteId, user).catch(err => {
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
throw err; throw err;
}); });
if ((!user.isAdmin && !user.isModerator) && (note.userId !== user.id)) { if ((!user.isAdmin && !user.isModerator) && (note.userId !== user.id)) {
throw new ApiError(meta.errors.accessDenied); throw new ApiError('ACCESS_DENIED');
} }
// この操作を行うのが投稿者とは限らない(例えばモデレーター)ため // この操作を行うのが投稿者とは限らない(例えばモデレーター)ため

View file

@ -11,19 +11,7 @@ export const meta = {
kind: 'write:favorites', kind: 'write:favorites',
errors: { errors: ['NO_SUCH_NOTE', 'ALREADY_FAVORITED'],
noSuchNote: {
message: 'No such note.',
code: 'NO_SUCH_NOTE',
id: '6dd26674-e060-4816-909a-45ba3f4da458',
},
alreadyFavorited: {
message: 'The note has already been marked as a favorite.',
code: 'ALREADY_FAVORITED',
id: 'a402c12b-34dd-41d2-97d8-4d2ffd96a1a6',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -38,7 +26,7 @@ export const paramDef = {
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
// Get favoritee // Get favoritee
const note = await getNote(ps.noteId, user).catch(err => { const note = await getNote(ps.noteId, user).catch(err => {
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
throw err; throw err;
}); });
@ -48,9 +36,7 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (exist != null) { if (exist != null) throw new ApiError('ALREADY_FAVORITED');
throw new ApiError(meta.errors.alreadyFavorited);
}
// Create favorite // Create favorite
await NoteFavorites.insert({ await NoteFavorites.insert({

View file

@ -10,19 +10,7 @@ export const meta = {
kind: 'write:favorites', kind: 'write:favorites',
errors: { errors: ['NO_SUCH_NOTE', 'NOT_FAVORITED'],
noSuchNote: {
message: 'No such note.',
code: 'NO_SUCH_NOTE',
id: '80848a2c-398f-4343-baa9-df1d57696c56',
},
notFavorited: {
message: 'You have not marked that note a favorite.',
code: 'NOT_FAVORITED',
id: 'b625fc69-635e-45e9-86f4-dbefbef35af5',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -37,7 +25,7 @@ export const paramDef = {
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
// Get favoritee // Get favoritee
const note = await getNote(ps.noteId, user).catch(err => { const note = await getNote(ps.noteId, user).catch(err => {
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
throw err; throw err;
}); });
@ -47,9 +35,7 @@ export default define(meta, paramDef, async (ps, user) => {
userId: user.id, userId: user.id,
}); });
if (exist == null) { if (exist == null) throw new ApiError('NOT_FAVORITED');
throw new ApiError(meta.errors.notFavorited);
}
// Delete favorite // Delete favorite
await NoteFavorites.delete(exist.id); await NoteFavorites.delete(exist.id);

View file

@ -23,13 +23,7 @@ export const meta = {
}, },
}, },
errors: { errors: ['TIMELINE_DISABLED'],
gtlDisabled: {
message: 'Global timeline has been disabled.',
code: 'GTL_DISABLED',
id: '0332fc13-6ab2-4427-ae80-a9fadffd1a6b',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -54,7 +48,7 @@ export default define(meta, paramDef, async (ps, user) => {
const m = await fetchMeta(); const m = await fetchMeta();
if (m.disableGlobalTimeline) { if (m.disableGlobalTimeline) {
if (user == null || (!user.isAdmin && !user.isModerator)) { if (user == null || (!user.isAdmin && !user.isModerator)) {
throw new ApiError(meta.errors.gtlDisabled); throw new ApiError('TIMELINE_DISABLED');
} }
} }

View file

@ -28,13 +28,7 @@ export const meta = {
}, },
}, },
errors: { errors: ['TIMELINE_DISABLED'],
stlDisabled: {
message: 'Hybrid timeline has been disabled.',
code: 'STL_DISABLED',
id: '620763f4-f621-4533-ab33-0577a1a3c342',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -61,7 +55,7 @@ export const paramDef = {
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
const m = await fetchMeta(); const m = await fetchMeta();
if (m.disableLocalTimeline && (!user.isAdmin && !user.isModerator)) { if (m.disableLocalTimeline && (!user.isAdmin && !user.isModerator)) {
throw new ApiError(meta.errors.stlDisabled); throw new ApiError('TIMELINE_DISABLED');
} }
//#region Construct query //#region Construct query

View file

@ -26,13 +26,7 @@ export const meta = {
}, },
}, },
errors: { errors: ['TIMELINE_DISABLED'],
ltlDisabled: {
message: 'Local timeline has been disabled.',
code: 'LTL_DISABLED',
id: '45a6eb02-7695-4393-b023-dd3be9aaaefd',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -61,7 +55,7 @@ export default define(meta, paramDef, async (ps, user) => {
const m = await fetchMeta(); const m = await fetchMeta();
if (m.disableLocalTimeline) { if (m.disableLocalTimeline) {
if (user == null || (!user.isAdmin && !user.isModerator)) { if (user == null || (!user.isAdmin && !user.isModerator)) {
throw new ApiError(meta.errors.ltlDisabled); throw new ApiError('TIMELINE_DISABLED');
} }
} }

View file

@ -19,50 +19,14 @@ export const meta = {
kind: 'write:votes', kind: 'write:votes',
errors: { errors: ['NO_SUCH_NOTE', 'INVALID_CHOICE', 'ALREADY_VOTED', 'EXPIRED_POLL', 'BLOCKED'],
noSuchNote: {
message: 'No such note.',
code: 'NO_SUCH_NOTE',
id: 'ecafbd2e-c283-4d6d-aecb-1a0a33b75396',
},
noPoll: {
message: 'The note does not attach a poll.',
code: 'NO_POLL',
id: '5f979967-52d9-4314-a911-1c673727f92f',
},
invalidChoice: {
message: 'Choice ID is invalid.',
code: 'INVALID_CHOICE',
id: 'e0cc9a04-f2e8-41e4-a5f1-4127293260cc',
},
alreadyVoted: {
message: 'You have already voted.',
code: 'ALREADY_VOTED',
id: '0963fc77-efac-419b-9424-b391608dc6d8',
},
alreadyExpired: {
message: 'The poll is already expired.',
code: 'ALREADY_EXPIRED',
id: '1022a357-b085-4054-9083-8f8de358337e',
},
youHaveBeenBlocked: {
message: 'You cannot vote this poll because you have been blocked by this user.',
code: 'YOU_HAVE_BEEN_BLOCKED',
id: '85a5377e-b1e9-4617-b0b9-5bea73331e49',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
type: 'object', type: 'object',
properties: { properties: {
noteId: { type: 'string', format: 'misskey:id' }, noteId: { type: 'string', format: 'misskey:id' },
choice: { type: 'integer' }, choice: { type: 'integer', minimum: 0 },
}, },
required: ['noteId', 'choice'], required: ['noteId', 'choice'],
} as const; } as const;
@ -73,12 +37,12 @@ export default define(meta, paramDef, async (ps, user) => {
// Get votee // Get votee
const note = await getNote(ps.noteId, user).catch(err => { const note = await getNote(ps.noteId, user).catch(err => {
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
throw err; throw err;
}); });
if (!note.hasPoll) { if (!note.hasPoll) {
throw new ApiError(meta.errors.noPoll); throw new ApiError('NO_SUCH_NOTE', 'The note exists but does not have a poll attached.');
} }
// Check blocking // Check blocking
@ -87,19 +51,17 @@ export default define(meta, paramDef, async (ps, user) => {
blockerId: note.userId, blockerId: note.userId,
blockeeId: user.id, blockeeId: user.id,
}); });
if (block) { if (block) throw new ApiError('BLOCKED');
throw new ApiError(meta.errors.youHaveBeenBlocked);
}
} }
const poll = await Polls.findOneByOrFail({ noteId: note.id }); const poll = await Polls.findOneByOrFail({ noteId: note.id });
if (poll.expiresAt && poll.expiresAt < createdAt) { if (poll.expiresAt && poll.expiresAt < createdAt) {
throw new ApiError(meta.errors.alreadyExpired); throw new ApiError('EXPIRED_POLL');
} }
if (poll.choices[ps.choice] == null) { if (poll.choices[ps.choice] == null) {
throw new ApiError(meta.errors.invalidChoice); throw new ApiError('INVALID_CHOICE', `There are only ${poll.choices.length} choices.`);
} }
// if already voted // if already voted
@ -111,10 +73,10 @@ export default define(meta, paramDef, async (ps, user) => {
if (exist.length) { if (exist.length) {
if (poll.multiple) { if (poll.multiple) {
if (exist.some(x => x.choice === ps.choice)) { if (exist.some(x => x.choice === ps.choice)) {
throw new ApiError(meta.errors.alreadyVoted); throw new ApiError('ALREADY_VOTED', 'This is a multiple choice poll, but you already voted for that option.');
} }
} else { } else {
throw new ApiError(meta.errors.alreadyVoted); throw new ApiError('ALREADY_VOTED', 'This is a single choice poll.');
} }
} }

View file

@ -23,13 +23,7 @@ export const meta = {
}, },
}, },
errors: { errors: ['NO_SUCH_NOTE'],
noSuchNote: {
message: 'No such note.',
code: 'NO_SUCH_NOTE',
id: '263fff3d-d0e1-4af4-bea7-8408059b451a',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -53,7 +47,7 @@ export const paramDef = {
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
// check note visibility // check note visibility
const note = await getNote(ps.noteId, user).catch(err => { const note = await getNote(ps.noteId, user).catch(err => {
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
throw err; throw err;
}); });

View file

@ -10,25 +10,7 @@ export const meta = {
kind: 'write:reactions', kind: 'write:reactions',
errors: { errors: ['NO_SUCH_NOTE', 'ALREADY_REACTED', 'BLOCKED'],
noSuchNote: {
message: 'No such note.',
code: 'NO_SUCH_NOTE',
id: '033d0620-5bfe-4027-965d-980b0c85a3ea',
},
alreadyReacted: {
message: 'You are already reacting to that note.',
code: 'ALREADY_REACTED',
id: '71efcf98-86d6-4e2b-b2ad-9d032369366b',
},
youHaveBeenBlocked: {
message: 'You cannot react this note because you have been blocked by this user.',
code: 'YOU_HAVE_BEEN_BLOCKED',
id: '20ef5475-9f38-4e4c-bd33-de6d979498ec',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -43,12 +25,12 @@ export const paramDef = {
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
const note = await getNote(ps.noteId, user).catch(err => { const note = await getNote(ps.noteId, user).catch(err => {
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
throw err; throw err;
}); });
await createReaction(user, note, ps.reaction).catch(e => { await createReaction(user, note, ps.reaction).catch(e => {
if (e.id === '51c42bb4-931a-456b-bff7-e5a8a70dd298') throw new ApiError(meta.errors.alreadyReacted); if (e.id === '51c42bb4-931a-456b-bff7-e5a8a70dd298') throw new ApiError('ALREADY_REACTED');
if (e.id === 'e70412a4-7197-4726-8e74-f3e0deb92aa7') throw new ApiError(meta.errors.youHaveBeenBlocked); if (e.id === 'e70412a4-7197-4726-8e74-f3e0deb92aa7') throw new ApiError('BLOCKED');
throw e; throw e;
}); });
return; return;

View file

@ -17,19 +17,7 @@ export const meta = {
minInterval: 3 * SECOND, minInterval: 3 * SECOND,
}, },
errors: { errors: ['NO_SUCH_NOTE', 'NOT_REACTED'],
noSuchNote: {
message: 'No such note.',
code: 'NO_SUCH_NOTE',
id: '764d9fce-f9f2-4a0e-92b1-6ceac9a7ad37',
},
notReacted: {
message: 'You are not reacting to that note.',
code: 'NOT_REACTED',
id: '92f4426d-4196-4125-aa5b-02943e2ec8fc',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -43,11 +31,11 @@ export const paramDef = {
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
const note = await getNote(ps.noteId, user).catch(err => { const note = await getNote(ps.noteId, user).catch(err => {
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
throw err; throw err;
}); });
await deleteReaction(user, note).catch(e => { await deleteReaction(user, note).catch(e => {
if (e.id === '60527ec9-b4cb-4a88-a6bd-32d3ad26817d') throw new ApiError(meta.errors.notReacted); if (e.id === '60527ec9-b4cb-4a88-a6bd-32d3ad26817d') throw new ApiError('NOT_REACTED');
throw e; throw e;
}); });
}); });

View file

@ -22,13 +22,7 @@ export const meta = {
}, },
}, },
errors: { errors: ['NO_SUCH_NOTE'],
noSuchNote: {
message: 'No such note.',
code: 'NO_SUCH_NOTE',
id: '12908022-2e21-46cd-ba6a-3edaf6093f46',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -45,7 +39,7 @@ export const paramDef = {
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
const note = await getNote(ps.noteId, user).catch(err => { const note = await getNote(ps.noteId, user).catch(err => {
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
throw err; throw err;
}); });

View file

@ -22,9 +22,6 @@ export const meta = {
ref: 'Note', ref: 'Note',
}, },
}, },
errors: {
},
} as const; } as const;
export const paramDef = { export const paramDef = {

View file

@ -14,13 +14,7 @@ export const meta = {
ref: 'Note', ref: 'Note',
}, },
errors: { errors: ['NO_SUCH_NOTE'],
noSuchNote: {
message: 'No such note.',
code: 'NO_SUCH_NOTE',
id: '24fcbfc6-2e37-42b6-8388-c29b3861a08d',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -34,7 +28,7 @@ export const paramDef = {
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
const note = await getNote(ps.noteId, user).catch(err => { const note = await getNote(ps.noteId, user).catch(err => {
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
throw err; throw err;
}); });
@ -42,7 +36,7 @@ export default define(meta, paramDef, async (ps, user) => {
// FIXME: packing with detail may throw an error if the reply or renote is not visible (#8774) // FIXME: packing with detail may throw an error if the reply or renote is not visible (#8774)
detail: true, detail: true,
}).catch(err => { }).catch(err => {
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
throw err; throw err;
}); });
}); });

View file

@ -13,13 +13,7 @@ export const meta = {
kind: 'write:account', kind: 'write:account',
errors: { errors: ['NO_SUCH_NOTE'],
noSuchNote: {
message: 'No such note.',
code: 'NO_SUCH_NOTE',
id: '5ff67ada-ed3b-2e71-8e87-a1a421e177d2',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -41,7 +35,7 @@ export const paramDef = {
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
const note = await getNote(ps.noteId, user).catch(err => { const note = await getNote(ps.noteId, user).catch(err => {
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
throw err; throw err;
}); });

View file

@ -10,13 +10,7 @@ export const meta = {
kind: 'write:account', kind: 'write:account',
errors: { errors: ['NO_SUCH_NOTE'],
noSuchNote: {
message: 'No such note.',
code: 'NO_SUCH_NOTE',
id: 'bddd57ac-ceb3-b29d-4334-86ea5fae481a',
},
},
} as const; } as const;
export const paramDef = { export const paramDef = {
@ -30,7 +24,7 @@ export const paramDef = {
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
const note = await getNote(ps.noteId, user).catch(err => { const note = await getNote(ps.noteId, user).catch(err => {
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
throw err; throw err;
}); });

View file

@ -55,13 +55,7 @@ export const meta = {
}, },
}, },
errors: { errors: ['NO_SUCH_NOTE'],
noSuchNote: {
message: 'No such note.',
code: 'NO_SUCH_NOTE',
id: 'bea9b03f-36e0-49c5-a4db-627a029f8971',
},
},
} as const; } as const;
// List of permitted languages from https://www.deepl.com/docs-api/translate-text/translate-text/ // List of permitted languages from https://www.deepl.com/docs-api/translate-text/translate-text/
@ -116,7 +110,7 @@ export const paramDef = {
// eslint-disable-next-line import/no-default-export // eslint-disable-next-line import/no-default-export
export default define(meta, paramDef, async (ps, user) => { export default define(meta, paramDef, async (ps, user) => {
const note = await getNote(ps.noteId, user).catch(err => { const note = await getNote(ps.noteId, user).catch(err => {
if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError(meta.errors.noSuchNote); if (err.id === '9725d0ce-ba28-4dde-95a7-2cbb2c15de24') throw new ApiError('NO_SUCH_NOTE');
throw err; throw err;
}); });

Some files were not shown because too many files have changed in this diff Show more