feat: isOakException完善,现在可以传入具体的Exception以判断

This commit is contained in:
Pan Qiancheng 2025-12-22 15:01:45 +08:00
parent b9a6b26b13
commit 473940214a
3 changed files with 111 additions and 5 deletions

View File

@ -2,7 +2,21 @@ import { StorageSchema } from ".";
import { EntityDict, OpRecord } from "./Entity";
import { EntityDict as BaseEntityDict } from '../base-app-domain';
declare const OAK_EXCEPTION_SYMBOL: unique symbol;
export declare function isOakException(obj: any): obj is OakException<any>;
/**
* OakException `instanceof`
* OakUserException继承自OakException使OakUserException以进一步确认类型
* @param obj
* @param exceptionName
*
* ```ts
* if (isOakException(e, OakUserException)) {
* // 这里的 e 已被类型缩小为 OakUserException
* }
* ```
*
* @returns OakException true false
*/
export declare function isOakException<T extends OakException<any>>(obj: any, errType?: new () => T): obj is T;
export declare class OakException<ED extends EntityDict & BaseEntityDict> extends Error {
opRecords: OpRecord<ED>[];
_module?: string;

View File

@ -6,8 +6,53 @@ exports.makeException = makeException;
const relation_1 = require("../store/relation");
const lodash_1 = require("../utils/lodash");
const OAK_EXCEPTION_SYMBOL = Symbol.for('oak-domain:exception');
function isOakException(obj) {
return obj && obj[OAK_EXCEPTION_SYMBOL] === true;
/**
* 判断一个对象是否为 OakException 实例作用和 `instanceof` 类似但更安全可靠
* 如OakUserException继承自OakException使用时可传入OakUserException以进一步确认类型
* @param obj 需要判断的对象
* @param exceptionName 可选参数指定异常类名以进一步确认
*
* ```ts
* if (isOakException(e, OakUserException)) {
* // 这里的 e 已被类型缩小为 OakUserException
* }
* ```
*
* @returns 如果对象是 OakException 实例则返回 true否则返回 false
*/
function isOakException(obj, errType) {
if (!obj) {
return false;
}
const isOakException = !!obj[OAK_EXCEPTION_SYMBOL];
if (isOakException) {
if (!errType) {
return true;
}
}
else {
return false;
}
try {
let proto = Object.getPrototypeOf(obj);
const expectedName = errType.name;
let depth = 0;
const maxDepth = 10; // 防止无限循环
while (proto && depth < maxDepth) {
const constructorName = proto.constructor?.name;
if (constructorName === expectedName) {
return true;
}
proto = Object.getPrototypeOf(proto);
depth++;
}
return false;
}
catch (e) {
console.warn(e);
// 如果检查过程出错,安全返回 false
return false;
}
}
class OakException extends Error {
opRecords;

View File

@ -7,8 +7,55 @@ import { pick } from '../utils/lodash';
const OAK_EXCEPTION_SYMBOL = Symbol.for('oak-domain:exception');
export function isOakException(obj: any): obj is OakException<any> {
return obj && obj[OAK_EXCEPTION_SYMBOL] === true;
/**
* OakException `instanceof`
* OakUserException继承自OakException使OakUserException以进一步确认类型
* @param obj
* @param exceptionName
*
* ```ts
* if (isOakException(e, OakUserException)) {
* // 这里的 e 已被类型缩小为 OakUserException
* }
* ```
*
* @returns OakException true false
*/
export function isOakException<T extends OakException<any>>(obj: any, errType?: new () => T): obj is T {
if (!obj) {
return false;
}
const isOakException = !!obj[OAK_EXCEPTION_SYMBOL];
if (isOakException) {
if (!errType) {
return true;
}
} else {
return false;
}
try {
let proto = Object.getPrototypeOf(obj);
const expectedName = errType.name;
let depth = 0;
const maxDepth = 10; // 防止无限循环
while (proto && depth < maxDepth) {
const constructorName = proto.constructor?.name;
if (constructorName === expectedName) {
return true;
}
proto = Object.getPrototypeOf(proto);
depth++;
}
return false;
} catch (e) {
console.warn(e);
// 如果检查过程出错,安全返回 false
return false;
}
}
export class OakException<ED extends EntityDict & BaseEntityDict> extends Error {