feat: enhance callRequest method with options validation and hook execution
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { isPublicMethod, ToDeepPromise } from "@/utils/utils";
|
||||
import { isArray, isObject, isPublicMethod, ToDeepPromise } from "@/utils/utils";
|
||||
import { RPCConnection } from "./RPCConnection";
|
||||
import { RPCHandler } from "./RPCHandler";
|
||||
import { RPCProvider } from "./RPCProvider";
|
||||
@@ -8,6 +8,7 @@ import { RPCError, RPCErrorCode } from "./RPCError";
|
||||
import { makeCallPacket, makeCallResponsePacket, parseCallPacket, parseCallResponsePacket } from "./RPCCommon";
|
||||
import { RPCPacket } from "./RPCPacket";
|
||||
import { EventEmitter } from "@/utils/EventEmitter";
|
||||
import { createHookRunner } from "./RPCPlugin";
|
||||
|
||||
function getProviderFunction(provider: RPCProvider, fnPath: string):
|
||||
[(...args: any[]) => Promise<any>, object] | null {
|
||||
@@ -111,6 +112,45 @@ export class RPCSession {
|
||||
});
|
||||
}
|
||||
|
||||
function setOptions(opt: unknown) {
|
||||
if (!isObject(opt)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ('fnPath' in opt && 'args' in opt && 'timeout' in opt) {
|
||||
const { fnPath, args, timeout } = opt;
|
||||
if (typeof fnPath !== 'string') {
|
||||
return;
|
||||
}
|
||||
if (!isArray(args)) {
|
||||
return;
|
||||
}
|
||||
if (typeof timeout !== 'number') {
|
||||
return;
|
||||
}
|
||||
options = {
|
||||
...options,
|
||||
fnPath,
|
||||
args,
|
||||
timeout,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const hookRunner = createHookRunner(this.rpcHandler.getPlugins(), 'onCallOutgoingBefore');
|
||||
await hookRunner({
|
||||
session: this,
|
||||
options: { ...options },
|
||||
setOptions,
|
||||
});
|
||||
|
||||
/** due to `await hookRunner` */
|
||||
if (this.connection.closed) {
|
||||
throw new RPCError({
|
||||
errorCode: RPCErrorCode.CONNECTION_DISCONNECTED,
|
||||
});
|
||||
}
|
||||
|
||||
const { fnPath, args } = options;
|
||||
const packet = makeCallPacket({
|
||||
fnPath,
|
||||
@@ -135,28 +175,75 @@ export class RPCSession {
|
||||
})();
|
||||
|
||||
const handleCallResponsePacket = (packet: RPCPacket) => {
|
||||
const result = parseCallResponsePacket(packet);
|
||||
if (result === null) {
|
||||
return reject(new RPCError({
|
||||
let result = parseCallResponsePacket(packet);
|
||||
function setResult(res: unknown) {
|
||||
if (!isObject(res)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { success, error } = res;
|
||||
|
||||
if (typeof success === 'object' && typeof error === 'object') {
|
||||
if (success && !error) {
|
||||
if ('data' in success) {
|
||||
result = {
|
||||
success: { data: success.data },
|
||||
error: null,
|
||||
}
|
||||
}
|
||||
} else if (!success && error) {
|
||||
const { errorCode, reason } = error;
|
||||
if (typeof errorCode === 'number' && typeof reason === 'string') {
|
||||
result = {
|
||||
success: null,
|
||||
error: {
|
||||
errorCode,
|
||||
reason,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const hookRunner = createHookRunner(this.rpcHandler.getPlugins(), 'onCallOutgoing');
|
||||
hookRunner({
|
||||
session: this,
|
||||
options: { ...options },
|
||||
setOptions,
|
||||
result,
|
||||
setResult,
|
||||
}).then(() => {
|
||||
if (result === null) {
|
||||
return reject(new RPCError({
|
||||
errorCode: RPCErrorCode.UNKNOWN_ERROR,
|
||||
}));;
|
||||
}
|
||||
|
||||
const { success, error } = result;
|
||||
if (success) {
|
||||
return resolve(success.data);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return reject(new RPCError({
|
||||
errorCode: error.errorCode,
|
||||
reason: error.reason
|
||||
}));
|
||||
}
|
||||
|
||||
reject(new RPCError({
|
||||
errorCode: RPCErrorCode.UNKNOWN_ERROR,
|
||||
}));;
|
||||
}
|
||||
}).catch((e) => {
|
||||
if (e instanceof RPCError) {
|
||||
return reject(e);
|
||||
}
|
||||
|
||||
const { success, error } = result;
|
||||
if (success) {
|
||||
return resolve(success.data);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return reject(new RPCError({
|
||||
errorCode: error.errorCode,
|
||||
reason: error.reason
|
||||
}));
|
||||
}
|
||||
|
||||
return reject(new RPCError({
|
||||
errorCode: RPCErrorCode.UNKNOWN_ERROR,
|
||||
}));;
|
||||
reject(new RPCError({
|
||||
errorCode: RPCErrorCode.UNKNOWN_ERROR,
|
||||
}))
|
||||
})
|
||||
}
|
||||
this.callResponseEmitter.once(packet.id, handleCallResponsePacket);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user