attach errorhandler to failed calls and failed connects
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "rpclibrary",
|
"name": "rpclibrary",
|
||||||
"version": "1.8.0",
|
"version": "1.8.1",
|
||||||
"description": "rpclibrary is a websocket on steroids!",
|
"description": "rpclibrary is a websocket on steroids!",
|
||||||
"main": "./js/Index.js",
|
"main": "./js/Index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ export class RPCServer<
|
|||||||
SubResType = {},
|
SubResType = {},
|
||||||
InterfaceT extends T.RPCInterface = T.RPCInterface,
|
InterfaceT extends T.RPCInterface = T.RPCInterface,
|
||||||
> implements I.Destroyable{
|
> implements I.Destroyable{
|
||||||
|
|
||||||
private ws = http.createServer()
|
private ws = http.createServer()
|
||||||
private io = bsock.createServer()
|
private io = bsock.createServer()
|
||||||
private visibility:T.Visibility
|
private visibility:T.Visibility
|
||||||
|
|||||||
+23
-8
@@ -18,8 +18,8 @@ export class RPCSocket implements I.Socket{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private socket: I.Socket
|
private socket: I.Socket
|
||||||
private closeHandlers: T.CloseHandler[] = []
|
private closeHandlers: T.FrontEndHandlerType['close'][] = []
|
||||||
private errorHandlers: T.ErrorHandler[] = []
|
private errorHandlers: T.FrontEndHandlerType['error'][] = []
|
||||||
private hooks : {[name in string]: T.AnyFunction} = {}
|
private hooks : {[name in string]: T.AnyFunction} = {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -62,11 +62,11 @@ export class RPCSocket implements I.Socket{
|
|||||||
* @param type 'error' or 'close'
|
* @param type 'error' or 'close'
|
||||||
* @param f The listener to attach
|
* @param f The listener to attach
|
||||||
*/
|
*/
|
||||||
public on<T extends "error" | "close">(type: T, f: T.HandlerType[T]){
|
public on<T extends "error" | "close">(type: T, f: T.FrontEndHandlerType[T]){
|
||||||
if(!this.socket){
|
if(!this.socket){
|
||||||
switch(type){
|
switch(type){
|
||||||
case "error": this.errorHandlers.push(<T.HandlerType['error']> f); break;
|
case "error": this.errorHandlers.push(<T.FrontEndHandlerType['error']> f); break;
|
||||||
case "close": this.closeHandlers.push(<T.HandlerType['close']> f); break;
|
case "close": this.closeHandlers.push(<T.FrontEndHandlerType['close']> f); break;
|
||||||
default: throw new Error('socket.on only supports ´error´ and ´close´ as first parameter. Got: ´'+type+'´')
|
default: throw new Error('socket.on only supports ´error´ and ´close´ as first parameter. Got: ´'+type+'´')
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
@@ -74,6 +74,16 @@ export class RPCSocket implements I.Socket{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emit a LOCAL event
|
||||||
|
* @param eventName The event name to emit under
|
||||||
|
* @param data The data the event carries
|
||||||
|
*/
|
||||||
|
public emit(eventName:string, data:any){
|
||||||
|
if(!this.socket) return
|
||||||
|
this.socket.emit(eventName, data)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroys the socket
|
* Destroys the socket
|
||||||
*/
|
*/
|
||||||
@@ -97,7 +107,11 @@ export class RPCSocket implements I.Socket{
|
|||||||
*/
|
*/
|
||||||
public async call (rpcname: string, ...args: any[]) : Promise<any>{
|
public async call (rpcname: string, ...args: any[]) : Promise<any>{
|
||||||
if(!this.socket) throw new Error("The socket is not connected! Use socket.connect() first")
|
if(!this.socket) throw new Error("The socket is not connected! Use socket.connect() first")
|
||||||
return await this.socket.call.apply(this.socket, [rpcname, ...args])
|
try{
|
||||||
|
return await this.socket.call.apply(this.socket, [rpcname, ...args])
|
||||||
|
}catch(e){
|
||||||
|
this.emit('error', e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -159,7 +173,9 @@ export class RPCSocket implements I.Socket{
|
|||||||
const argParams = fnArgs.map(stripAfterEquals).join(",")
|
const argParams = fnArgs.map(stripAfterEquals).join(",")
|
||||||
sesame = appendComma(sesame)
|
sesame = appendComma(sesame)
|
||||||
|
|
||||||
return eval(`async (${headerArgs}) => { return await this.socket.call("${fnName}", ${sesame} ${argParams})}`)
|
return eval(`async (${headerArgs}) => {
|
||||||
|
return await this.socket.call("${fnName}", ${sesame} ${argParams})
|
||||||
|
}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -179,7 +195,6 @@ export class RPCSocket implements I.Socket{
|
|||||||
|
|
||||||
return eval( `
|
return eval( `
|
||||||
async (${headerArgs} callback) => {
|
async (${headerArgs} callback) => {
|
||||||
|
|
||||||
const r = await this.socket.call("${fnName}", ${sesame} ${argParams})
|
const r = await this.socket.call("${fnName}", ${sesame} ${argParams})
|
||||||
if(r && r.result === 'Success'){
|
if(r && r.result === 'Success'){
|
||||||
this.socket.hook(r.uuid, callback)
|
this.socket.hook(r.uuid, callback)
|
||||||
|
|||||||
+2
-1
@@ -22,7 +22,8 @@ export interface Socket extends Destroyable {
|
|||||||
unhook: (rpcname:string) => void
|
unhook: (rpcname:string) => void
|
||||||
call: (rpcname:string, ...args: any[]) => Promise<any>
|
call: (rpcname:string, ...args: any[]) => Promise<any>
|
||||||
fire: (rpcname:string, ...args: any[]) => Promise<any>
|
fire: (rpcname:string, ...args: any[]) => Promise<any>
|
||||||
on: T.OnFunction
|
on: T.OnFunction
|
||||||
|
emit: (eventName: string, data:any) => void
|
||||||
close() : void
|
close() : void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -12,9 +12,9 @@ export type ExceptionHandling = 'local' | 'remote'
|
|||||||
export type SesameConf = {
|
export type SesameConf = {
|
||||||
sesame?: string | SesameFunction
|
sesame?: string | SesameFunction
|
||||||
}
|
}
|
||||||
export type HandlerType = {
|
export type FrontEndHandlerType = {
|
||||||
'error' : ErrorHandler
|
'error' : (e: any) => void
|
||||||
'close' : CloseHandler
|
'close' : () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ServerConf = {
|
export type ServerConf = {
|
||||||
@@ -84,5 +84,5 @@ export type CallInfo = BaseInfo & {
|
|||||||
export type RpcInfo = HookInfo | CallInfo
|
export type RpcInfo = HookInfo | CallInfo
|
||||||
export type ExtendedRpcInfo = RpcInfo & { uniqueName: string }
|
export type ExtendedRpcInfo = RpcInfo & { uniqueName: string }
|
||||||
|
|
||||||
export type OnFunction = <T extends "error" | "close">(type: T, f: HandlerType[T]) => void
|
export type OnFunction = <T extends "error" | "close">(type: T, f: FrontEndHandlerType[T]) => void
|
||||||
export type HookCloseFunction<T = {}> = (res:SubscriptionResponse<T>, rpc:HookRPC<any, any, T>) => any
|
export type HookCloseFunction<T = {}> = (res:SubscriptionResponse<T>, rpc:HookRPC<any, any, T>) => any
|
||||||
|
|||||||
+44
-6
@@ -551,14 +551,17 @@ describe("Class binding", ()=>{
|
|||||||
|
|
||||||
}
|
}
|
||||||
let serv: RPCServer,
|
let serv: RPCServer,
|
||||||
sock: RPCSocket,
|
sock: RPCSocket & myExporterIfc,
|
||||||
exporter: MyExporter
|
exporter: MyExporter
|
||||||
|
|
||||||
before((done)=>{
|
before((done)=>{
|
||||||
exporter = new MyExporter()
|
exporter = new MyExporter()
|
||||||
serv = new RPCServer(21004, [exporter])
|
serv = new RPCServer(21004, [exporter])
|
||||||
sock = new RPCSocket(21004, 'localhost')
|
const s = new RPCSocket(21004, 'localhost')
|
||||||
sock.connect<myExporterIfc>().then(_ => done())
|
s.connect<myExporterIfc>().then(conn => {
|
||||||
|
sock = conn
|
||||||
|
done()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
after(() => {
|
after(() => {
|
||||||
sock.destroy()
|
sock.destroy()
|
||||||
@@ -574,13 +577,11 @@ describe("Class binding", ()=>{
|
|||||||
|
|
||||||
|
|
||||||
describe("attaching handlers before connecting", ()=>{
|
describe("attaching handlers before connecting", ()=>{
|
||||||
|
|
||||||
|
|
||||||
it("fires error if server is unreachable", (done)=>{
|
it("fires error if server is unreachable", (done)=>{
|
||||||
const sock = new RPCSocket(21004, 'localhost')
|
const sock = new RPCSocket(21004, 'localhost')
|
||||||
let errorHandleCount = 0
|
let errorHandleCount = 0
|
||||||
|
|
||||||
sock.on('error', (socket) => {
|
sock.on('error', (err) => {
|
||||||
//attached listener fires first
|
//attached listener fires first
|
||||||
if(errorHandleCount != 0){
|
if(errorHandleCount != 0){
|
||||||
console.log("Error handler didn't fire first");
|
console.log("Error handler didn't fire first");
|
||||||
@@ -601,4 +602,41 @@ describe("attaching handlers before connecting", ()=>{
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("fires error if call is unknown", (done)=>{
|
||||||
|
const serv = new RPCServer(21004)
|
||||||
|
const sock = new RPCSocket(21004, 'localhost')
|
||||||
|
|
||||||
|
sock.on('error', (err) => {
|
||||||
|
sock.destroy()
|
||||||
|
serv.destroy()
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
|
||||||
|
sock.connect().then(_ => {
|
||||||
|
sock.call("unknownRPC123", "AAAAA").catch(e => {
|
||||||
|
console.log("unexpected call catch clause");
|
||||||
|
done(e)
|
||||||
|
})
|
||||||
|
}).catch(e => {
|
||||||
|
console.log("unexpected connect catch clause");
|
||||||
|
done(e)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("demands catch on method invocation if call is unknown", (done)=>{
|
||||||
|
const serv = new RPCServer(21004)
|
||||||
|
const sock = new RPCSocket(21004, 'localhost')
|
||||||
|
|
||||||
|
sock.connect().then(_ => {
|
||||||
|
sock.call("unknownRPC123", "AAAAA").catch(e => {
|
||||||
|
sock.destroy()
|
||||||
|
serv.destroy()
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
}).catch(e => {
|
||||||
|
console.log("unexpected connect catch clause");
|
||||||
|
done(e)
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
Reference in New Issue
Block a user