Browse Source

attach errorhandler to failed calls and failed connects

master
peter 4 years ago
parent
commit
bc7593bda5
6 changed files with 75 additions and 20 deletions
  1. 1
    1
      package.json
  2. 1
    0
      src/Backend.ts
  3. 23
    8
      src/Frontend.ts
  4. 2
    1
      src/Interfaces.ts
  5. 4
    4
      src/Types.ts
  6. 44
    6
      test/Test.ts

+ 1
- 1
package.json View File

@@ -1,6 +1,6 @@
1 1
 {
2 2
   "name": "rpclibrary",
3
-  "version": "1.8.0",
3
+  "version": "1.8.1",
4 4
   "description": "rpclibrary is a websocket on steroids!",
5 5
   "main": "./js/Index.js",
6 6
   "repository": {

+ 1
- 0
src/Backend.ts View File

@@ -14,6 +14,7 @@ export class RPCServer<
14 14
     SubResType = {},
15 15
     InterfaceT extends T.RPCInterface = T.RPCInterface,
16 16
 > implements I.Destroyable{
17
+    
17 18
     private ws = http.createServer()
18 19
     private io = bsock.createServer()
19 20
     private visibility:T.Visibility

+ 23
- 8
src/Frontend.ts View File

@@ -18,8 +18,8 @@ export class RPCSocket implements I.Socket{
18 18
     }
19 19
 
20 20
     private socket: I.Socket
21
-    private closeHandlers: T.CloseHandler[] = []
22
-    private errorHandlers: T.ErrorHandler[] = []
21
+    private closeHandlers: T.FrontEndHandlerType['close'][] = []
22
+    private errorHandlers: T.FrontEndHandlerType['error'][] = []
23 23
     private hooks : {[name in string]: T.AnyFunction} = {} 
24 24
 
25 25
     /**
@@ -62,11 +62,11 @@ export class RPCSocket implements I.Socket{
62 62
      * @param type 'error' or 'close'
63 63
      * @param f The listener to attach
64 64
      */
65
-    public on<T extends "error" | "close">(type: T, f: T.HandlerType[T]){
65
+    public on<T extends "error" | "close">(type: T, f: T.FrontEndHandlerType[T]){
66 66
         if(!this.socket){
67 67
             switch(type){
68
-                case "error": this.errorHandlers.push(<T.HandlerType['error']> f); break;
69
-                case "close": this.closeHandlers.push(<T.HandlerType['close']> f); break;
68
+                case "error": this.errorHandlers.push(<T.FrontEndHandlerType['error']> f); break;
69
+                case "close": this.closeHandlers.push(<T.FrontEndHandlerType['close']> f); break;
70 70
                 default: throw new Error('socket.on only supports ´error´ and ´close´ as first parameter. Got: ´'+type+'´')
71 71
             }
72 72
         }else{
@@ -74,6 +74,16 @@ export class RPCSocket implements I.Socket{
74 74
         }
75 75
     }
76 76
 
77
+    /**
78
+     * Emit a LOCAL event
79
+     * @param eventName The event name to emit under
80
+     * @param data The data the event carries
81
+     */
82
+    public emit(eventName:string, data:any){
83
+        if(!this.socket) return
84
+        this.socket.emit(eventName, data)
85
+    }
86
+
77 87
     /**
78 88
      * Destroys the socket
79 89
      */
@@ -97,7 +107,11 @@ export class RPCSocket implements I.Socket{
97 107
      */
98 108
     public async call (rpcname: string, ...args: any[]) : Promise<any>{
99 109
         if(!this.socket) throw new Error("The socket is not connected! Use socket.connect() first")
100
-        return await this.socket.call.apply(this.socket, [rpcname, ...args])
110
+        try{
111
+            return await this.socket.call.apply(this.socket, [rpcname, ...args])
112
+        }catch(e){
113
+            this.emit('error', e)
114
+        }
101 115
     }
102 116
 
103 117
     /**
@@ -159,7 +173,9 @@ export class RPCSocket implements I.Socket{
159 173
         const argParams = fnArgs.map(stripAfterEquals).join(",")
160 174
         sesame = appendComma(sesame)
161 175
 
162
-        return eval(`async (${headerArgs}) => { return await this.socket.call("${fnName}", ${sesame} ${argParams})}`)
176
+        return eval(`async (${headerArgs}) => { 
177
+            return await this.socket.call("${fnName}", ${sesame} ${argParams})
178
+        }`)
163 179
     }
164 180
 
165 181
     /**
@@ -179,7 +195,6 @@ export class RPCSocket implements I.Socket{
179 195
 
180 196
         return eval( `
181 197
         async (${headerArgs} callback) => {
182
-
183 198
             const r = await this.socket.call("${fnName}", ${sesame} ${argParams})
184 199
             if(r && r.result === 'Success'){
185 200
                 this.socket.hook(r.uuid, callback)

+ 2
- 1
src/Interfaces.ts View File

@@ -22,7 +22,8 @@ export interface Socket extends Destroyable {
22 22
     unhook: (rpcname:string) => void
23 23
     call: (rpcname:string, ...args: any[]) => Promise<any>
24 24
     fire: (rpcname:string, ...args: any[]) => Promise<any>
25
-    on: T.OnFunction    
25
+    on: T.OnFunction
26
+    emit: (eventName: string, data:any) => void    
26 27
     close() : void
27 28
 }
28 29
 

+ 4
- 4
src/Types.ts View File

@@ -12,9 +12,9 @@ export type ExceptionHandling = 'local' | 'remote'
12 12
 export type SesameConf = {
13 13
     sesame?: string | SesameFunction
14 14
 }
15
-export type HandlerType = {
16
-    'error' : ErrorHandler
17
-    'close' : CloseHandler
15
+export type FrontEndHandlerType = {
16
+    'error' : (e: any) => void
17
+    'close' : () => void
18 18
 }
19 19
 
20 20
 export type ServerConf = {
@@ -84,5 +84,5 @@ export type CallInfo = BaseInfo & {
84 84
 export type RpcInfo = HookInfo |  CallInfo
85 85
 export type ExtendedRpcInfo = RpcInfo & { uniqueName: string } 
86 86
 
87
-export type OnFunction = <T extends "error" | "close">(type: T, f: HandlerType[T]) => void
87
+export type OnFunction = <T extends "error" | "close">(type: T, f: FrontEndHandlerType[T]) => void
88 88
 export type HookCloseFunction<T = {}> = (res:SubscriptionResponse<T>, rpc:HookRPC<any, any, T>) => any

+ 44
- 6
test/Test.ts View File

@@ -551,14 +551,17 @@ describe("Class binding", ()=>{
551 551
 
552 552
     }
553 553
     let serv: RPCServer,
554
-        sock: RPCSocket,
554
+        sock: RPCSocket & myExporterIfc,
555 555
         exporter: MyExporter
556 556
         
557 557
     before((done)=>{
558 558
         exporter = new MyExporter()
559 559
         serv = new RPCServer(21004, [exporter])
560
-        sock = new RPCSocket(21004, 'localhost')
561
-        sock.connect<myExporterIfc>().then(_ => done())
560
+        const s = new RPCSocket(21004, 'localhost')
561
+        s.connect<myExporterIfc>().then(conn => {
562
+            sock = conn
563
+            done()
564
+        })
562 565
     })
563 566
     after(() => {
564 567
         sock.destroy()
@@ -574,13 +577,11 @@ describe("Class binding", ()=>{
574 577
 
575 578
 
576 579
 describe("attaching handlers before connecting", ()=>{
577
-
578
-
579 580
     it("fires error if server is unreachable", (done)=>{
580 581
         const sock = new RPCSocket(21004, 'localhost')
581 582
         let errorHandleCount = 0
582 583
 
583
-        sock.on('error', (socket) => {
584
+        sock.on('error', (err) => {
584 585
             //attached listener fires first
585 586
             if(errorHandleCount != 0){
586 587
                 console.log("Error handler didn't fire first");
@@ -601,4 +602,41 @@ describe("attaching handlers before connecting", ()=>{
601 602
             }
602 603
         })
603 604
     })
605
+
606
+    it("fires error if call is unknown", (done)=>{
607
+        const serv = new RPCServer(21004)
608
+        const sock = new RPCSocket(21004, 'localhost')
609
+
610
+        sock.on('error', (err) => {
611
+            sock.destroy()
612
+            serv.destroy()
613
+            done()
614
+        })
615
+
616
+        sock.connect().then(_ => {
617
+            sock.call("unknownRPC123", "AAAAA").catch(e => {
618
+                console.log("unexpected call catch clause");
619
+                done(e)
620
+            })
621
+        }).catch(e => {
622
+            console.log("unexpected connect catch clause");
623
+            done(e)
624
+        })
625
+    })
626
+
627
+    it("demands catch on method invocation if call is unknown", (done)=>{
628
+        const serv = new RPCServer(21004)
629
+        const sock = new RPCSocket(21004, 'localhost')
630
+
631
+        sock.connect().then(_ => {
632
+            sock.call("unknownRPC123", "AAAAA").catch(e => {
633
+                sock.destroy()
634
+                serv.destroy()
635
+                done()
636
+            })
637
+        }).catch(e => {
638
+            console.log("unexpected connect catch clause");
639
+            done(e)
640
+        })
641
+    })
604 642
 })

Loading…
Cancel
Save