oak-domain/src/types/Exception.ts

261 lines
7.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { EntityDict, OpRecord } from "./Entity";
export class OakException extends Error {
constructor(message?: string) {
super(message);
this.name = new.target.name;
if (typeof (Error as any).captureStackTrace === 'function') {
(Error as any).captureStackTrace(this, new.target);
}
if (typeof Object.setPrototypeOf === 'function') {
Object.setPrototypeOf(this, new.target.prototype);
} else {
(this as any).__proto__ = new.target.prototype;
}
}
toString() {
return JSON.stringify({
name: this.constructor.name,
message: this.message,
});
}
}
export class OakDataException extends OakException {
// 表示由数据层发现的异常
}
export class OakUniqueViolationException extends OakException {
rows: Array<{
id?: string;
attrs: string[];
}>;
constructor(rows: Array<{
id?: string;
attrs: string[];
}>, message?: string) {
super(message || '您更新的数据违反了唯一性约束');
this.rows = rows;
}
}
export class OakImportDataParseException extends OakException {
line: number;
header?: string;
// message必传描述具体错误的数据内容
constructor(message: string, line: number, header?: string) {
super(message);
this.line = line;
this.header = header;
}
}
export class OakOperExistedException extends OakDataException {
// 进行操作时发现同样id的Oper对象已经存在
}
export class OakRowUnexistedException extends OakDataException {
private rows: Array<{
entity: any;
selection: any;
}>
// 指定主键查询时却发现行不存在,一般发生在缓存中
constructor(rows: Array<{entity: any, selection: any}>) {
super(`查询${rows.map(ele => ele.entity).join(',')}对象时发现了空指针,请检查数据一致性`);
this.rows = rows;
}
toString() {
return JSON.stringify({rows: this.rows });
}
getRows() {
return this.rows;
}
}
export class OakExternalException extends Error {
// 表示由oak生态外部造成的异常比如网络中断
}
export class OakUserException extends OakException {
// 继承了这个类的异常统一视为“可接受的、由用户操作造成的异常”
};
// 在系统更新数据时,以下三个异常应按规范依次抛出。
/**
* 数据不一致异常,系统认为现有的数据不允许相应的动作时抛此异常
*
*/
export class OakRowInconsistencyException<ED extends EntityDict> extends OakUserException {
private data?: OpRecord<ED>;
constructor(data?: OpRecord<ED>, message?: string) {
super(message);
this.data = data;
}
getData() {
return this.data;
}
toString(): string {
return JSON.stringify({
name: this.constructor.name,
message: this.message,
data: this.data,
});
}
};
/**
* 当输入的数据非法时抛此异常attributes表示非法的属性
*/
export class OakInputIllegalException extends OakUserException {
private attributes: string[];
private entity: string;
constructor(entity: string, attributes: string[], message?: string) {
super(message);
this.entity = entity;
this.attributes = attributes;
}
getEntity() {
return this.entity;
}
getAttributes() {
return this.attributes;
}
addAttributesPrefix(prefix: string) {
this.attributes = this.attributes.map(
ele => `${prefix}.${ele}`
);
}
toString(): string {
return JSON.stringify({
entity: this.entity,
name: this.constructor.name,
message: this.message,
attributes: this.attributes,
});
}
};
/**
* 用户权限不够时抛的异常
*/
export class OakUserUnpermittedException extends OakUserException {
};
/**
* 用户未登录抛的异常
*/
export class OakUnloggedInException extends OakUserException {
constructor(message?: string) {
super(message || '您尚未登录');
}
};
/**
* 用户未登录抛的异常
*/
export class OakRowLockedException extends OakUserException {
constructor(message?: string) {
super(message || '该行数据正在被更新中,请稍后再试');
}
};
/**
* 要插入行时,发现已经有相同的行数据
*/
export class OakCongruentRowExists<ED extends EntityDict, T extends keyof ED> extends OakUserException {
private data: ED[T]['OpSchema'];
private entity: T;
constructor(entity: T, data: ED[T]['OpSchema'], message?: string) {
super(message);
this.data = data;
this.entity = entity;
}
getData() {
return this.data;
}
getEntity() {
return this.entity;
}
toString(): string {
return JSON.stringify({
name: this.constructor.name,
message: this.message,
data: this.data,
entity: this.entity,
});
}
}
export class OakDeadlock extends OakUserException {
constructor(message?: string | undefined) {
super(message || '发现死锁');
}
};
export function makeException(data: {
name: string;
message?: string;
[A: string]: any;
}) {
const { name } = data;
switch (name) {
case 'OakException': {
return new OakException(data.message);
}
case 'OakUserException': {
return new OakUserException(data.message);
}
case 'OakExternalException': {
return new OakExternalException(data.message);
}
case 'OakRowInconsistencyException': {
return new OakRowInconsistencyException(data.data, data.message);
}
case 'OakInputIllegalException': {
return new OakInputIllegalException(data.entity, data.attributes, data.message);
}
case 'OakUserUnpermittedException': {
return new OakUserUnpermittedException(data.message);
}
case 'OakUnloggedInException': {
return new OakUnloggedInException(data.message);
}
case 'OakCongruentRowExists': {
return new OakCongruentRowExists(data.entity, data.data, data.message);
}
case 'OakRowLockedException': {
return new OakRowLockedException(data.message);
}
case 'OakRowUnexistedException': {
return new OakRowUnexistedException(data.rows);
}
case 'OakDeadlock': {
return new OakDeadlock(data.message);
}
case 'OakDataException': {
return new OakDataException(data.message);
}
case 'OakUniqueViolationException': {
return new OakUniqueViolationException(data.rows, data.message);
}
case 'OakImportDataParseException': {
return new OakImportDataParseException(data.message!, data.line, data.header);
}
default:
return;
}
}