core: send: 区分远端错误与本地错误

This commit is contained in:
undefined committed 2021-02-28 13:28:01 +08:00
1 parent 6f96e7fa9e
commit f2fbbb8af9
4 files changed
+29 -10

No files matched your search

+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "hydrooj",
"version": "2.18.1",
"version": "2.18.2",
"bin": "bin/hydrooj.js",
"main": "dist/loader.js",
"typings": "dist/loader.d.ts",
@@ -61,4 +61,4 @@
"build": "tsc",
"build:watch": "tsc --watch"
}
}
}
+15 -5
View File
@@ -1,7 +1,8 @@
/* eslint-disable no-await-in-loop */
import superagent from 'superagent';
import { PassThrough } from 'stream';
import { PermissionError, InvalidTokenError } from '../error';
import { PermissionError, InvalidTokenError, RemoteOnlineJudgeError } from '../error';
import { Logger } from '../logger';
import { ProblemAdd } from '../lib/ui';
import { PERM } from '../model/builtin';
import * as token from '../model/token';
@@ -11,6 +12,9 @@ import {
Handler, Types, Route, post,
} from '../service/server';
import storage from '../service/storage';
import { logAndReturn } from '../utils';
const logger = new Logger('remote');
export class ProblemSendHandler extends Handler {
async get() {
@@ -23,10 +27,13 @@ export class ProblemSendHandler extends Handler {
target = target.split('@');
const getHidden = this.user.hasPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN);
const getData = this.user.hasPerm(PERM.PERM_READ_PROBLEM_DATA);
const pdocs = await problem.getList(domainId, _pids, getHidden, true, ['docId', 'owner']);
const pdocs = await problem.getList(domainId, _pids, true, true, ['docId', 'owner', 'hidden']);
const pids = new Set<number>();
for (const key in pdocs) {
pids.add(pdocs[key].docId);
if (pdocs[key].hidden && !getHidden && pdocs[key].owner !== this.user._id) {
throw new PermissionError(PERM.PERM_VIEW_PROBLEM_HIDDEN);
}
if (!getData && pdocs[key].owner !== this.user._id) {
throw new PermissionError(PERM.PERM_READ_PROBLEM_DATA);
}
@@ -36,7 +43,7 @@ export class ProblemSendHandler extends Handler {
await superagent.post(`${target[1]}/d/${target[0]}/problem/receive`)
.send({
operation: 'request', url: `${url}d/${domainId}/problem/send`, tokenId, expire,
});
}).catch(logAndReturn(logger));
this.back();
}
@@ -87,7 +94,9 @@ export class ProblemReceiveHandler extends Handler {
@post('expire', Types.UnsignedInt)
async postRequest(domainId: string, url: string, tokenId: string, expire: number) {
const res = await superagent.post(url)
.send({ operation: 'info', token: tokenId });
.send({ operation: 'info', token: tokenId })
.catch(logAndReturn(logger));
if (res instanceof Error) throw new RemoteOnlineJudgeError(res.message);
const [id] = await token.add(token.TYPE_IMPORT, expire, {
domainId, tokenId, source: url, pdocs: res.body.pdocs, pids: res.body.pids,
});
@@ -117,7 +126,8 @@ export class ProblemReceiveHandler extends Handler {
operation: 'fetch',
token: data.tokenId,
pids: filterPid.length ? filterPid.map((i) => (+i ? +i : i)) : data.pids,
});
}).catch(logAndReturn(logger));
if (res instanceof Error) throw new RemoteOnlineJudgeError(res.message);
const tasks = [];
const pids = [];
const { pdocs } = res.body;
+3 -2
View File
@@ -3,7 +3,7 @@ import { argv } from 'yargs';
import { Time } from './utils';
const instances: Record<string, Logger> = {};
type LogFunction = (format: any, ...param: any[]) => void;
type LogFunction = (format: any, ...param: any[]) => boolean;
type LogType = 'success' | 'error' | 'info' | 'warn' | 'debug';
export interface Logger extends Record<LogType, LogFunction> { }
export class Logger {
@@ -37,10 +37,11 @@ export class Logger {
private createMethod(name: LogType, prefix: string, minLevel: number) {
this[name] = (...args: [any, ...any[]]) => {
if (this.level < minLevel) return;
if (this.level < minLevel) return false;
const msg = `${prefix} ${this.name} ${this.format(...args)}`;
if (process.send) process.send({ event: 'message/log', payload: [msg] });
else global.Hydro.service.bus.parallel('message/log', msg);
return true;
};
}
+9 -1
View File
@@ -6,7 +6,8 @@ import serialize from 'serialize-javascript';
import Lru from 'lru-cache';
import { ObjectID } from 'mongodb';
import { isMoment } from 'moment';
import { Moment } from 'moment-timezone';
import type { Moment } from 'moment-timezone';
import type { Logger } from './logger';
declare global {
interface StringConstructor {
@@ -220,6 +221,13 @@ function deepen(modifyString: (source: string) => string) {
};
}
export function logAndReturn(logger: Logger) {
return function cb(err: Error) {
logger.error(err);
return err;
};
}
export const camelCase = deepen((source) => source.replace(/[_-][a-z]/g, (str) => str.slice(1).toUpperCase()));
export const paramCase = deepen((source) => source.replace(/_/g, '-').replace(/(?<!^)[A-Z]/g, (str) => `-${str.toLowerCase()}`));
export const snakeCase = deepen((source) => source.replace(/-/g, '_').replace(/(?<!^)[A-Z]/g, (str) => `_${str.toLowerCase()}`));