Skip to content

Commit 614cb27

Browse files
authoredJun 19, 2021
Merge pull request #14 from EnCiv/stream-err
catch the stream error and reset
2 parents 2de8676 + 1a32418 commit 614cb27

File tree

5 files changed

+77
-12
lines changed

5 files changed

+77
-12
lines changed
 

‎app/server/socket-api.js

+16-5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ function handlerWrapper(handler, handle, ...args) {
1616
}
1717
}
1818

19+
function handlerStreamWrapper(handler, handle, ...args) {
20+
try {
21+
handler.call(this, ...args)
22+
} catch (error) {
23+
logger.error('caught error from stream api handler', handle, error.message, 'continuing', error)
24+
}
25+
}
26+
1927
class API {
2028
constructor() {
2129
this.users = []
@@ -65,6 +73,7 @@ class API {
6573
.on('connect_timeout', error => {
6674
logger.error('socket io connection_timeout', error, this)
6775
})
76+
.on('error', err => logger.error('socketAPI server caught error', err))
6877
} catch (error) {
6978
logger.error('API start caught error', error)
7079
}
@@ -144,17 +153,19 @@ class API {
144153
socket.emit('OK ' + event, ...responses)
145154
}
146155

147-
socket.error = error => {
148-
logger.error('api connected socket.error caught error', error)
149-
}
150156
var ssSocket
151157

152158
for (let handle in this.handlers) {
153159
if (handle.endsWith('development') && process.env.NODE_ENV !== 'development') continue // ignore handlers that end with "development" in production
154160
if (handle.startsWith('stream')) {
155-
if (!ssSocket) ssSocket = ss(socket)
161+
if (!ssSocket) {
162+
ssSocket = ss(socket)
163+
ssSocket.on('error', err => logger.error('socket-api ssSocket error', err))
164+
ssSocket.on('uncaughtException', err => logger.error('socket uncaught', err))
165+
ssSocket.on('close', () => console.error('got close'))
166+
}
156167
// handlers that use streams need to start with 'stream' and they are wrapped differently to work
157-
ssSocket.on(handle, handlerWrapper.bind(ssSocket, this.handlers[handle], handle))
168+
ssSocket.on(handle, handlerStreamWrapper.bind(ssSocket, this.handlers[handle], handle))
158169
} else socket.on(handle, handlerWrapper.bind(socket, this.handlers[handle], handle))
159170
}
160171
// thanks to https://stackoverflow.com/questions/41751141/socket-io-how-to-access-unhandled-messages

‎app/server/the-civil-server.js

+5
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ class HttpServer {
4545
this.App = App
4646
this.setUserCookie = setUserCookie.bind(this) // user cookie needs this context so it doesn't have to lookup users in the DB every time
4747
this.socketAPI = new SocketAPI()
48+
if (process.listeners('uncaughtException') === 0) {
49+
process.on('uncaughtException', err => {
50+
logger.error('theCivliServer: Uncaught Exception thrown\n', err, '\ncontinuing')
51+
})
52+
}
4853
}
4954

5055
addRoutesDirectory(dirPath) {

‎app/socket-apis/stream-test-development.js

+8-6
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
const { pipeline } = require('stream')
33

44
export default function streamTest(stream) {
5-
try {
6-
console.info('stream test on server', stream)
7-
pipeline(stream, process.stdout, err => err && console.log(err))
8-
} catch (err) {
9-
console.info('streamTest caught error', err)
10-
}
5+
console.info('stream test on server', stream)
6+
let self = this // is an ss(socket)
7+
pipeline(stream, process.stdout, err => {
8+
process.stdout.end()
9+
self._ondisconnect()
10+
self.sio.disconnect(true)
11+
err && console.error(err)
12+
})
1113
}

‎app/tools/stream-test.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22
const { pipeline } = require('stream')
33
const ss = require('@sap_oss/node-socketio-stream')
44

5+
var host = process.argv[2] || 'http://localhost:3011'
6+
console.info('target is', host)
7+
58
// client side
69
const client = require('socket.io-client')
7-
const socket = client.connect('http://localhost:3011')
10+
const socket = client.connect(host)
811

912
socket.on('connect', () => {
1013
var stream = ss.createStream()

‎test-socket-error.js

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
const express = require('express')
2+
const socketio = require('socket.io')
3+
const http = require('http')
4+
5+
const PORT = process.env.PORT || 8000
6+
7+
const app = express()
8+
const server = http.createServer(app)
9+
const io = socketio(server)
10+
11+
server.listen(PORT, () => {
12+
console.log(`Listening on port ${PORT}`)
13+
})
14+
15+
const checkLength = bar => {
16+
console.info('bar', bar)
17+
if (bar.length > 14) {
18+
console.info('throwing error')
19+
throw Error('word is too long!')
20+
}
21+
// ...
22+
}
23+
24+
io.on('connection', socket => {
25+
console.log('new socket connection')
26+
27+
socket.on('foo', bar => {
28+
try {
29+
checkLength(bar)
30+
} catch (e) {
31+
console.info('caught error', e)
32+
socket.emit('oops', e.message)
33+
return
34+
}
35+
console.log('app did not crash!')
36+
})
37+
})
38+
39+
const client = require('socket.io-client')
40+
const socket = client.connect('http://localhost:8000')
41+
socket.on('connect', () => {
42+
socket.emit('foo', '123456789012345')
43+
console.info('emitted')
44+
})

0 commit comments

Comments
 (0)