Better error handling

This commit is contained in:
syuilo 2019-04-14 04:17:24 +09:00
parent 7e83f50c1b
commit 1b3848ee5d
25 changed files with 52 additions and 52 deletions

View File

@ -14,6 +14,6 @@ export function genId(date?: Date): string {
case 'meid': return genMeid(date); case 'meid': return genMeid(date);
case 'ulid': return ulid(date.getTime()); case 'ulid': return ulid(date.getTime());
case 'objectid': return genObjectId(date); case 'objectid': return genObjectId(date);
default: throw 'unknown id generation method'; default: throw new Error('unknown id generation method');
} }
} }

View File

@ -3,7 +3,7 @@
*/ */
export function ensure<T>(x: T): NonNullable<T> { export function ensure<T>(x: T): NonNullable<T> {
if (x == null) { if (x == null) {
throw 'ぬるぽ'; throw new Error('ぬるぽ');
} else { } else {
return x!; return x!;
} }

View File

@ -6,7 +6,7 @@ import { Users } from '../../../../models';
export default async (actor: IRemoteUser, activity: IFollow): Promise<void> => { export default async (actor: IRemoteUser, activity: IFollow): Promise<void> => {
const id = typeof activity.actor == 'string' ? activity.actor : activity.actor.id; const id = typeof activity.actor == 'string' ? activity.actor : activity.actor.id;
if (id == null) throw 'missing id'; if (id == null) throw new Error('missing id');
if (!id.startsWith(config.url + '/')) { if (!id.startsWith(config.url + '/')) {
return; return;

View File

@ -9,7 +9,7 @@ const logger = apLogger;
export default async (actor: IRemoteUser, activity: IBlock): Promise<void> => { export default async (actor: IRemoteUser, activity: IBlock): Promise<void> => {
const id = typeof activity.object == 'string' ? activity.object : activity.object.id; const id = typeof activity.object == 'string' ? activity.object : activity.object.id;
if (id == null) throw 'missing id'; if (id == null) throw new Error('missing id');
const uri = activity.id || activity; const uri = activity.id || activity;

View File

@ -6,7 +6,7 @@ import { Users } from '../../../models';
export default async (actor: IRemoteUser, activity: IFollow): Promise<void> => { export default async (actor: IRemoteUser, activity: IFollow): Promise<void> => {
const id = typeof activity.object == 'string' ? activity.object : activity.object.id; const id = typeof activity.object == 'string' ? activity.object : activity.object.id;
if (id == null) throw 'missing id'; if (id == null) throw new Error('missing id');
if (!id.startsWith(config.url + '/')) { if (!id.startsWith(config.url + '/')) {
return; return;

View File

@ -5,7 +5,7 @@ import { Notes } from '../../../models';
export default async (actor: IRemoteUser, activity: ILike) => { export default async (actor: IRemoteUser, activity: ILike) => {
const id = typeof activity.object == 'string' ? activity.object : activity.object.id; const id = typeof activity.object == 'string' ? activity.object : activity.object.id;
if (id == null) throw 'missing id'; if (id == null) throw new Error('missing id');
// Transform: // Transform:
// https://misskey.ex/notes/xxxx to // https://misskey.ex/notes/xxxx to

View File

@ -6,7 +6,7 @@ import { Users } from '../../../../models';
export default async (actor: IRemoteUser, activity: IFollow): Promise<void> => { export default async (actor: IRemoteUser, activity: IFollow): Promise<void> => {
const id = typeof activity.actor == 'string' ? activity.actor : activity.actor.id; const id = typeof activity.actor == 'string' ? activity.actor : activity.actor.id;
if (id == null) throw 'missing id'; if (id == null) throw new Error('missing id');
if (!id.startsWith(config.url + '/')) { if (!id.startsWith(config.url + '/')) {
return; return;

View File

@ -9,7 +9,7 @@ const logger = apLogger;
export default async (actor: IRemoteUser, activity: IBlock): Promise<void> => { export default async (actor: IRemoteUser, activity: IBlock): Promise<void> => {
const id = typeof activity.object == 'string' ? activity.object : activity.object.id; const id = typeof activity.object == 'string' ? activity.object : activity.object.id;
if (id == null) throw 'missing id'; if (id == null) throw new Error('missing id');
const uri = activity.id || activity; const uri = activity.id || activity;

View File

@ -7,7 +7,7 @@ import { Users, FollowRequests, Followings } from '../../../../models';
export default async (actor: IRemoteUser, activity: IFollow): Promise<void> => { export default async (actor: IRemoteUser, activity: IFollow): Promise<void> => {
const id = typeof activity.object == 'string' ? activity.object : activity.object.id; const id = typeof activity.object == 'string' ? activity.object : activity.object.id;
if (id == null) throw 'missing id'; if (id == null) throw new Error('missing id');
if (!id.startsWith(config.url + '/')) { if (!id.startsWith(config.url + '/')) {
return; return;

View File

@ -8,13 +8,13 @@ import { Notes } from '../../../../models';
*/ */
export default async (actor: IRemoteUser, activity: ILike): Promise<void> => { export default async (actor: IRemoteUser, activity: ILike): Promise<void> => {
const id = typeof activity.object == 'string' ? activity.object : activity.object.id; const id = typeof activity.object == 'string' ? activity.object : activity.object.id;
if (id == null) throw 'missing id'; if (id == null) throw new Error('missing id');
const noteId = id.split('/').pop(); const noteId = id.split('/').pop();
const note = await Notes.findOne(noteId); const note = await Notes.findOne(noteId);
if (note == null) { if (note == null) {
throw 'note not found'; throw new Error('note not found');
} }
await deleteReaction(actor, note); await deleteReaction(actor, note);

View File

@ -32,7 +32,7 @@ const logger = apLogger;
*/ */
export async function fetchNote(value: string | IObject, resolver?: Resolver): Promise<Note | null> { export async function fetchNote(value: string | IObject, resolver?: Resolver): Promise<Note | null> {
const uri = typeof value == 'string' ? value : value.id; const uri = typeof value == 'string' ? value : value.id;
if (uri == null) throw 'missing uri'; if (uri == null) throw new Error('missing uri');
// URIがこのサーバーを指しているならデータベースからフェッチ // URIがこのサーバーを指しているならデータベースからフェッチ
if (uri.startsWith(config.url + '/')) { if (uri.startsWith(config.url + '/')) {
@ -67,7 +67,7 @@ export async function createNote(value: any, resolver?: Resolver, silent = false
value: value, value: value,
object: object object: object
}); });
throw 'invalid note'; throw new Error('invalid note');
} }
const note: INote = object; const note: INote = object;
@ -81,7 +81,7 @@ export async function createNote(value: any, resolver?: Resolver, silent = false
// 投稿者が凍結されていたらスキップ // 投稿者が凍結されていたらスキップ
if (actor.isSuspended) { if (actor.isSuspended) {
throw 'actor has been suspended'; throw new Error('actor has been suspended');
} }
//#region Visibility //#region Visibility
@ -124,7 +124,7 @@ export async function createNote(value: any, resolver?: Resolver, silent = false
? await resolveNote(note.inReplyTo, resolver).then(x => { ? await resolveNote(note.inReplyTo, resolver).then(x => {
if (x == null) { if (x == null) {
logger.warn(`Specified inReplyTo, but nout found`); logger.warn(`Specified inReplyTo, but nout found`);
throw 'inReplyTo not found'; throw new Error('inReplyTo not found');
} else { } else {
return x; return x;
} }
@ -230,7 +230,7 @@ export async function createNote(value: any, resolver?: Resolver, silent = false
*/ */
export async function resolveNote(value: string | IObject, resolver?: Resolver): Promise<Note | null> { export async function resolveNote(value: string | IObject, resolver?: Resolver): Promise<Note | null> {
const uri = typeof value == 'string' ? value : value.id; const uri = typeof value == 'string' ? value : value.id;
if (uri == null) throw 'missing uri'; if (uri == null) throw new Error('missing uri');
// ブロックしてたら中断 // ブロックしてたら中断
// TODO: いちいちデータベースにアクセスするのはコスト高そうなのでどっかにキャッシュしておく // TODO: いちいちデータベースにアクセスするのはコスト高そうなのでどっかにキャッシュしておく
@ -252,7 +252,7 @@ export async function resolveNote(value: string | IObject, resolver?: Resolver):
if (e.name === 'duplicated') { if (e.name === 'duplicated') {
return fetchNote(uri).then(note => { return fetchNote(uri).then(note => {
if (note == null) { if (note == null) {
throw 'something happened'; throw new Error('something happened');
} else { } else {
return note; return note;
} }

View File

@ -88,7 +88,7 @@ function validatePerson(x: any, uri: string) {
* Misskeyに対象のPersonが登録されていればそれを返します * Misskeyに対象のPersonが登録されていればそれを返します
*/ */
export async function fetchPerson(uri: string, resolver?: Resolver): Promise<User | null> { export async function fetchPerson(uri: string, resolver?: Resolver): Promise<User | null> {
if (typeof uri !== 'string') throw 'uri is not string'; if (typeof uri !== 'string') throw new Error('uri is not string');
// URIがこのサーバーを指しているならデータベースからフェッチ // URIがこのサーバーを指しているならデータベースからフェッチ
if (uri.startsWith(config.url + '/')) { if (uri.startsWith(config.url + '/')) {
@ -111,7 +111,7 @@ export async function fetchPerson(uri: string, resolver?: Resolver): Promise<Use
* Personを作成します * Personを作成します
*/ */
export async function createPerson(uri: string, resolver?: Resolver): Promise<User> { export async function createPerson(uri: string, resolver?: Resolver): Promise<User> {
if (typeof uri !== 'string') throw 'uri is not string'; if (typeof uri !== 'string') throw new Error('uri is not string');
if (resolver == null) resolver = new Resolver(); if (resolver == null) resolver = new Resolver();
@ -256,7 +256,7 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us
* @param hint Hint of Person object (Personの場合Remote resolveをせずに更新に利用します) * @param hint Hint of Person object (Personの場合Remote resolveをせずに更新に利用します)
*/ */
export async function updatePerson(uri: string, resolver?: Resolver | null, hint?: object): Promise<void> { export async function updatePerson(uri: string, resolver?: Resolver | null, hint?: object): Promise<void> {
if (typeof uri !== 'string') throw 'uri is not string'; if (typeof uri !== 'string') throw new Error('uri is not string');
// URIがこのサーバーを指しているならスキップ // URIがこのサーバーを指しているならスキップ
if (uri.startsWith(config.url + '/')) { if (uri.startsWith(config.url + '/')) {
@ -380,7 +380,7 @@ export async function updatePerson(uri: string, resolver?: Resolver | null, hint
* Misskeyに登録しそれを返します * Misskeyに登録しそれを返します
*/ */
export async function resolvePerson(uri: string, resolver?: Resolver): Promise<User> { export async function resolvePerson(uri: string, resolver?: Resolver): Promise<User> {
if (typeof uri !== 'string') throw 'uri is not string'; if (typeof uri !== 'string') throw new Error('uri is not string');
//#region このサーバーに既に登録されていたらそれを返す //#region このサーバーに既に登録されていたらそれを返す
const exist = await fetchPerson(uri); const exist = await fetchPerson(uri);

View File

@ -11,7 +11,7 @@ export async function extractPollFromQuestion(source: string | IQuestion): Promi
const expiresAt = question.endTime ? new Date(question.endTime) : null; const expiresAt = question.endTime ? new Date(question.endTime) : null;
if (multiple && !question.anyOf) { if (multiple && !question.anyOf) {
throw 'invalid question'; throw new Error('invalid question');
} }
const choices = question[multiple ? 'anyOf' : 'oneOf']! const choices = question[multiple ? 'anyOf' : 'oneOf']!
@ -37,14 +37,14 @@ export async function updateQuestion(value: any) {
const uri = typeof value == 'string' ? value : value.id; const uri = typeof value == 'string' ? value : value.id;
// URIがこのサーバーを指しているならスキップ // URIがこのサーバーを指しているならスキップ
if (uri.startsWith(config.url + '/')) throw 'uri points local'; if (uri.startsWith(config.url + '/')) throw new Error('uri points local');
//#region このサーバーに既に登録されているか //#region このサーバーに既に登録されているか
const note = await Notes.findOne({ uri }); const note = await Notes.findOne({ uri });
if (note == null) throw 'Question is not registed'; if (note == null) throw new Error('Question is not registed');
const poll = await Polls.findOne({ noteId: note.id }); const poll = await Polls.findOne({ noteId: note.id });
if (poll == null) throw 'Question is not registed'; if (poll == null) throw new Error('Question is not registed');
//#endregion //#endregion
// resolve new Question object // resolve new Question object
@ -52,7 +52,7 @@ export async function updateQuestion(value: any) {
const question = await resolver.resolve(value) as IQuestion; const question = await resolver.resolve(value) as IQuestion;
apLogger.debug(`fetched question: ${JSON.stringify(question, null, 2)}`); apLogger.debug(`fetched question: ${JSON.stringify(question, null, 2)}`);
if (question.type !== 'Question') throw 'object is not a Question'; if (question.type !== 'Question') throw new Error('object is not a Question');
const apChoices = question.oneOf || question.anyOf; const apChoices = question.oneOf || question.anyOf;

View File

@ -17,7 +17,7 @@ export async function resolveUser(username: string, host: string | null, option?
logger.info(`return local user: ${usernameLower}`); logger.info(`return local user: ${usernameLower}`);
return await Users.findOne({ usernameLower, host: null }).then(u => { return await Users.findOne({ usernameLower, host: null }).then(u => {
if (u == null) { if (u == null) {
throw 'user not found'; throw new Error('user not found');
} else { } else {
return u; return u;
} }
@ -30,7 +30,7 @@ export async function resolveUser(username: string, host: string | null, option?
logger.info(`return local user: ${usernameLower}`); logger.info(`return local user: ${usernameLower}`);
return await Users.findOne({ usernameLower, host: null }).then(u => { return await Users.findOne({ usernameLower, host: null }).then(u => {
if (u == null) { if (u == null) {
throw 'user not found'; throw new Error('user not found');
} else { } else {
return u; return u;
} }
@ -78,7 +78,7 @@ export async function resolveUser(username: string, host: string | null, option?
logger.info(`return resynced remote user: ${acctLower}`); logger.info(`return resynced remote user: ${acctLower}`);
return await Users.findOne({ uri: self.href }).then(u => { return await Users.findOne({ uri: self.href }).then(u => {
if (u == null) { if (u == null) {
throw 'user not found'; throw new Error('user not found');
} else { } else {
return u; return u;
} }

View File

@ -14,7 +14,7 @@ export default async (token: string): Promise<[User | null | undefined, App | nu
.findOne({ token }); .findOne({ token });
if (user == null) { if (user == null) {
throw 'user not found'; throw new Error('user not found');
} }
return [user, null]; return [user, null];
@ -24,7 +24,7 @@ export default async (token: string): Promise<[User | null | undefined, App | nu
}); });
if (accessToken == null) { if (accessToken == null) {
throw 'invalid signature'; throw new Error('invalid signature');
} }
const app = await Apps const app = await Apps

View File

@ -36,7 +36,7 @@ export async function getRemoteUser(userId: User['id']) {
const user = await getUser(userId); const user = await getUser(userId);
if (!Users.isRemoteUser(user)) { if (!Users.isRemoteUser(user)) {
throw 'user is not a remote user'; throw new Error('user is not a remote user');
} }
return user; return user;
@ -49,7 +49,7 @@ export async function getLocalUser(userId: User['id']) {
const user = await getUser(userId); const user = await getUser(userId);
if (!Users.isLocalUser(user)) { if (!Users.isLocalUser(user)) {
throw 'user is not a local user'; throw new Error('user is not a local user');
} }
return user; return user;

View File

@ -43,7 +43,7 @@ export default class extends Channel {
if (this.user == null) return; if (this.user == null) return;
const game = await ReversiGames.findOne(this.gameId!); const game = await ReversiGames.findOne(this.gameId!);
if (game == null) throw 'game not found'; if (game == null) throw new Error('game not found');
if (game.isStarted) return; if (game.isStarted) return;
if ((game.user1Id !== this.user.id) && (game.user2Id !== this.user.id)) return; if ((game.user1Id !== this.user.id) && (game.user2Id !== this.user.id)) return;
@ -67,7 +67,7 @@ export default class extends Channel {
if (this.user == null) return; if (this.user == null) return;
const game = await ReversiGames.findOne(this.gameId!); const game = await ReversiGames.findOne(this.gameId!);
if (game == null) throw 'game not found'; if (game == null) throw new Error('game not found');
if (game.isStarted) return; if (game.isStarted) return;
if ((game.user1Id !== this.user.id) && (game.user2Id !== this.user.id)) return; if ((game.user1Id !== this.user.id) && (game.user2Id !== this.user.id)) return;
@ -91,7 +91,7 @@ export default class extends Channel {
if (this.user == null) return; if (this.user == null) return;
const game = await ReversiGames.findOne(this.gameId!); const game = await ReversiGames.findOne(this.gameId!);
if (game == null) throw 'game not found'; if (game == null) throw new Error('game not found');
if (game.isStarted) return; if (game.isStarted) return;
if ((game.user1Id !== this.user.id) && (game.user2Id !== this.user.id)) return; if ((game.user1Id !== this.user.id) && (game.user2Id !== this.user.id)) return;
@ -135,7 +135,7 @@ export default class extends Channel {
if (this.user == null) return; if (this.user == null) return;
const game = await ReversiGames.findOne(this.gameId!); const game = await ReversiGames.findOne(this.gameId!);
if (game == null) throw 'game not found'; if (game == null) throw new Error('game not found');
if (game.isStarted) return; if (game.isStarted) return;
@ -237,7 +237,7 @@ export default class extends Channel {
if (this.user == null) return; if (this.user == null) return;
const game = await ReversiGames.findOne(this.gameId!); const game = await ReversiGames.findOne(this.gameId!);
if (game == null) throw 'game not found'; if (game == null) throw new Error('game not found');
if (!game.isStarted) return; if (!game.isStarted) return;
if (game.isEnded) return; if (game.isEnded) return;
@ -304,7 +304,7 @@ export default class extends Channel {
@autobind @autobind
private async check(crc32: string) { private async check(crc32: string) {
const game = await ReversiGames.findOne(this.gameId!); const game = await ReversiGames.findOne(this.gameId!);
if (game == null) throw 'game not found'; if (game == null) throw new Error('game not found');
if (!game.isStarted) return; if (!game.isStarted) return;

View File

@ -297,7 +297,7 @@ export default async function(
// If usage limit exceeded // If usage limit exceeded
if (usage + size > driveCapacity) { if (usage + size > driveCapacity) {
if (Users.isLocalUser(user)) { if (Users.isLocalUser(user)) {
throw 'no-free-space'; throw new Error('no-free-space');
} else { } else {
// (アバターまたはバナーを含まず)最も古いファイルを削除する // (アバターまたはバナーを含まず)最も古いファイルを削除する
deleteOldFile(user as IRemoteUser); deleteOldFile(user as IRemoteUser);
@ -316,7 +316,7 @@ export default async function(
userId: user.id userId: user.id
}); });
if (driveFolder == null) throw 'folder-not-found'; if (driveFolder == null) throw new Error('folder-not-found');
return driveFolder; return driveFolder;
}; };

View File

@ -78,7 +78,7 @@ export async function removePinned(user: User, noteId: Note['id']) {
export async function deliverPinnedChange(userId: User['id'], noteId: Note['id'], isAddition: boolean) { export async function deliverPinnedChange(userId: User['id'], noteId: Note['id'], isAddition: boolean) {
const user = await Users.findOne(userId); const user = await Users.findOne(userId);
if (user == null) throw 'user not found'; if (user == null) throw new Error('user not found');
if (!Users.isLocalUser(user)) return; if (!Users.isLocalUser(user)) return;

View File

@ -7,7 +7,7 @@ import { renderPerson } from '../../remote/activitypub/renderer/person';
export async function publishToFollowers(userId: User['id']) { export async function publishToFollowers(userId: User['id']) {
const user = await Users.findOne(userId); const user = await Users.findOne(userId);
if (user == null) throw 'user not found'; if (user == null) throw new Error('user not found');
const followers = await Followings.find({ const followers = await Followings.find({
followeeId: user.id followeeId: user.id

View File

@ -175,7 +175,7 @@ export default async (user: User, data: Option, silent = false) => new Promise<N
} }
if (data.visibility == 'specified') { if (data.visibility == 'specified') {
if (data.visibleUsers == null) throw 'invalid param'; if (data.visibleUsers == null) throw new Error('invalid param');
for (const u of data.visibleUsers) { for (const u of data.visibleUsers) {
if (!mentionedUsers.some(x => x.id === u.id)) { if (!mentionedUsers.some(x => x.id === u.id)) {
@ -214,7 +214,7 @@ export default async (user: User, data: Option, silent = false) => new Promise<N
// 未読通知を作成 // 未読通知を作成
if (data.visibility == 'specified') { if (data.visibility == 'specified') {
if (data.visibleUsers == null) throw 'invalid param'; if (data.visibleUsers == null) throw new Error('invalid param');
for (const u of data.visibleUsers) { for (const u of data.visibleUsers) {
insertNoteUnread(u, note, true); insertNoteUnread(u, note, true);
@ -428,7 +428,7 @@ async function insertNote(user: User, data: Option, tags: string[], emojis: stri
console.error(e); console.error(e);
throw 'something happened'; throw new Error('something happened');
} }
} }

View File

@ -7,10 +7,10 @@ import { Note } from '../../../models/entities/note';
export async function deliverQuestionUpdate(noteId: Note['id']) { export async function deliverQuestionUpdate(noteId: Note['id']) {
const note = await Notes.findOne(noteId); const note = await Notes.findOne(noteId);
if (note == null) throw 'note not found'; if (note == null) throw new Error('note not found');
const user = await Users.findOne(note.userId); const user = await Users.findOne(note.userId);
if (user == null) throw 'note not found'; if (user == null) throw new Error('note not found');
const followers = await Followings.find({ const followers = await Followings.find({
followeeId: user.id followeeId: user.id

View File

@ -10,7 +10,7 @@ import { createNotification } from '../../create-notification';
export default async function(user: User, note: Note, choice: number) { export default async function(user: User, note: Note, choice: number) {
const poll = await Polls.findOne(note.id); const poll = await Polls.findOne(note.id);
if (poll == null) throw 'poll not found'; if (poll == null) throw new Error('poll not found');
// Check whether is valid choice // Check whether is valid choice
if (poll.choices[choice] == null) throw new Error('invalid choice param'); if (poll.choices[choice] == null) throw new Error('invalid choice param');

View File

@ -18,8 +18,8 @@ const args = process.argv.slice(2);
const name = args[0]; const name = args[0];
const url = args[1]; const url = args[1];
if (!name) throw 'require name'; if (!name) throw new Error('require name');
if (!url) throw 'require url'; if (!url) throw new Error('require url');
main(name, url).then(() => { main(name, url).then(() => {
console.log('success'); console.log('success');

View File

@ -15,7 +15,7 @@ async function main(username: string, headers?: string[]) {
usernameLower: username.toLowerCase(), usernameLower: username.toLowerCase(),
}); });
if (user == null) throw 'User not found'; if (user == null) throw new Error('User not found');
const history = await Signins.find({ const history = await Signins.find({
userId: user.id userId: user.id