mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-15 14:43:46 +01:00
[misc] OError.tag all the errors in async contexts
See the docs of OError.tag: https://github.com/overleaf/o-error#long-stack-traces-with-oerrortag (currently at 221dd902e7bfa0ee92de1ea5a3cbf3152c3ceeb4) I am tagging all errors at each async hop. Most of the controller code will only ever see already tagged errors -- or new errors created in our app code. They should have enough info that we do not need to tag them again.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
const logger = require('logger-sharelatex')
|
const logger = require('logger-sharelatex')
|
||||||
const metrics = require('metrics-sharelatex')
|
const metrics = require('metrics-sharelatex')
|
||||||
const settings = require('settings-sharelatex')
|
const settings = require('settings-sharelatex')
|
||||||
|
const OError = require('@overleaf/o-error')
|
||||||
|
|
||||||
const ClientMap = new Map() // for each redis client, store a Map of subscribed channels (channelname -> subscribe promise)
|
const ClientMap = new Map() // for each redis client, store a Map of subscribed channels (channelname -> subscribe promise)
|
||||||
|
|
||||||
@@ -35,6 +36,8 @@ module.exports = {
|
|||||||
.catch(function (err) {
|
.catch(function (err) {
|
||||||
logger.error({ channel, err }, 'failed to subscribe to channel')
|
logger.error({ channel, err }, 'failed to subscribe to channel')
|
||||||
metrics.inc(`subscribe.failed.${baseChannel}`)
|
metrics.inc(`subscribe.failed.${baseChannel}`)
|
||||||
|
// add context for the stack-trace at the call-site
|
||||||
|
OError.tag(err, 'failed to subscribe to channel', { channel })
|
||||||
})
|
})
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ const async = require('async')
|
|||||||
const Settings = require('settings-sharelatex')
|
const Settings = require('settings-sharelatex')
|
||||||
const logger = require('logger-sharelatex')
|
const logger = require('logger-sharelatex')
|
||||||
const redis = require('redis-sharelatex')
|
const redis = require('redis-sharelatex')
|
||||||
|
const OError = require('@overleaf/o-error')
|
||||||
const rclient = redis.createClient(Settings.redis.realtime)
|
const rclient = redis.createClient(Settings.redis.realtime)
|
||||||
const Keys = Settings.redis.realtime.key_schema
|
const Keys = Settings.redis.realtime.key_schema
|
||||||
|
|
||||||
@@ -67,10 +68,7 @@ module.exports = {
|
|||||||
|
|
||||||
multi.exec(function (err) {
|
multi.exec(function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
logger.err(
|
OError.tag(err, 'problem marking user as connected')
|
||||||
{ err, project_id, client_id },
|
|
||||||
'problem marking user as connected'
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
callback(err)
|
callback(err)
|
||||||
})
|
})
|
||||||
@@ -104,7 +102,12 @@ module.exports = {
|
|||||||
multi.srem(Keys.clientsInProject({ project_id }), client_id)
|
multi.srem(Keys.clientsInProject({ project_id }), client_id)
|
||||||
multi.expire(Keys.clientsInProject({ project_id }), FOUR_DAYS_IN_S)
|
multi.expire(Keys.clientsInProject({ project_id }), FOUR_DAYS_IN_S)
|
||||||
multi.del(Keys.connectedUser({ project_id, client_id }))
|
multi.del(Keys.connectedUser({ project_id, client_id }))
|
||||||
multi.exec(callback)
|
multi.exec(function (err) {
|
||||||
|
if (err) {
|
||||||
|
OError.tag(err, 'problem marking user as disconnected')
|
||||||
|
}
|
||||||
|
callback(err)
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
_getConnectedUser(project_id, client_id, callback) {
|
_getConnectedUser(project_id, client_id, callback) {
|
||||||
@@ -112,6 +115,12 @@ module.exports = {
|
|||||||
err,
|
err,
|
||||||
result
|
result
|
||||||
) {
|
) {
|
||||||
|
if (err) {
|
||||||
|
OError.tag(err, 'problem fetching connected user details', {
|
||||||
|
other_client_id: client_id
|
||||||
|
})
|
||||||
|
return callback(err)
|
||||||
|
}
|
||||||
if (!(result && result.user_id)) {
|
if (!(result && result.user_id)) {
|
||||||
result = {
|
result = {
|
||||||
connected: false,
|
connected: false,
|
||||||
@@ -126,15 +135,10 @@ module.exports = {
|
|||||||
try {
|
try {
|
||||||
result.cursorData = JSON.parse(result.cursorData)
|
result.cursorData = JSON.parse(result.cursorData)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error(
|
OError.tag(e, 'error parsing cursorData JSON', {
|
||||||
{
|
other_client_id: client_id,
|
||||||
err: e,
|
cursorData: result.cursorData
|
||||||
project_id,
|
})
|
||||||
client_id,
|
|
||||||
cursorData: result.cursorData
|
|
||||||
},
|
|
||||||
'error parsing cursorData JSON'
|
|
||||||
)
|
|
||||||
return callback(e)
|
return callback(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -150,6 +154,7 @@ module.exports = {
|
|||||||
results
|
results
|
||||||
) {
|
) {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
OError.tag(err, 'problem getting clients in project')
|
||||||
return callback(err)
|
return callback(err)
|
||||||
}
|
}
|
||||||
const jobs = results.map((client_id) => (cb) =>
|
const jobs = results.map((client_id) => (cb) =>
|
||||||
@@ -157,6 +162,7 @@ module.exports = {
|
|||||||
)
|
)
|
||||||
async.series(jobs, function (err, users) {
|
async.series(jobs, function (err, users) {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
OError.tag(err, 'problem getting connected users')
|
||||||
return callback(err)
|
return callback(err)
|
||||||
}
|
}
|
||||||
users = users.filter(
|
users = users.filter(
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
const request = require('request')
|
const request = require('request')
|
||||||
const _ = require('underscore')
|
const _ = require('underscore')
|
||||||
|
const OError = require('@overleaf/o-error')
|
||||||
const logger = require('logger-sharelatex')
|
const logger = require('logger-sharelatex')
|
||||||
const settings = require('settings-sharelatex')
|
const settings = require('settings-sharelatex')
|
||||||
const metrics = require('metrics-sharelatex')
|
const metrics = require('metrics-sharelatex')
|
||||||
@@ -23,10 +24,7 @@ const DocumentUpdaterManager = {
|
|||||||
request.get(url, function (err, res, body) {
|
request.get(url, function (err, res, body) {
|
||||||
timer.done()
|
timer.done()
|
||||||
if (err) {
|
if (err) {
|
||||||
logger.error(
|
OError.tag(err, 'error getting doc from doc updater')
|
||||||
{ err, url, project_id, doc_id },
|
|
||||||
'error getting doc from doc updater'
|
|
||||||
)
|
|
||||||
return callback(err)
|
return callback(err)
|
||||||
}
|
}
|
||||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||||
@@ -37,6 +35,7 @@ const DocumentUpdaterManager = {
|
|||||||
try {
|
try {
|
||||||
body = JSON.parse(body)
|
body = JSON.parse(body)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
OError.tag(error, 'error parsing doc updater response')
|
||||||
return callback(error)
|
return callback(error)
|
||||||
}
|
}
|
||||||
body = body || {}
|
body = body || {}
|
||||||
@@ -79,10 +78,7 @@ const DocumentUpdaterManager = {
|
|||||||
request.del(url, function (err, res) {
|
request.del(url, function (err, res) {
|
||||||
timer.done()
|
timer.done()
|
||||||
if (err) {
|
if (err) {
|
||||||
logger.error(
|
OError.tag(err, 'error deleting project from document updater')
|
||||||
{ err, project_id },
|
|
||||||
'error deleting project from document updater'
|
|
||||||
)
|
|
||||||
callback(err)
|
callback(err)
|
||||||
} else if (res.statusCode >= 200 && res.statusCode < 300) {
|
} else if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||||
logger.log({ project_id }, 'deleted project from document updater')
|
logger.log({ project_id }, 'deleted project from document updater')
|
||||||
@@ -140,9 +136,15 @@ const DocumentUpdaterManager = {
|
|||||||
error
|
error
|
||||||
) {
|
) {
|
||||||
if (error) {
|
if (error) {
|
||||||
|
OError.tag(error, 'error pushing update into redis')
|
||||||
return callback(error)
|
return callback(error)
|
||||||
}
|
}
|
||||||
rclient.rpush('pending-updates-list', doc_key, callback)
|
rclient.rpush('pending-updates-list', doc_key, function (error) {
|
||||||
|
if (error) {
|
||||||
|
OError.tag(error, 'error pushing doc_id into redis')
|
||||||
|
}
|
||||||
|
callback(error)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
const logger = require('logger-sharelatex')
|
const logger = require('logger-sharelatex')
|
||||||
const metrics = require('metrics-sharelatex')
|
const metrics = require('metrics-sharelatex')
|
||||||
const { EventEmitter } = require('events')
|
const { EventEmitter } = require('events')
|
||||||
|
const OError = require('@overleaf/o-error')
|
||||||
|
|
||||||
const IdMap = new Map() // keep track of whether ids are from projects or docs
|
const IdMap = new Map() // keep track of whether ids are from projects or docs
|
||||||
const RoomEvents = new EventEmitter() // emits {project,doc}-active and {project,doc}-empty events
|
const RoomEvents = new EventEmitter() // emits {project,doc}-active and {project,doc}-empty events
|
||||||
@@ -65,6 +66,10 @@ module.exports = {
|
|||||||
logger.log({ entity, id }, 'room is now active')
|
logger.log({ entity, id }, 'room is now active')
|
||||||
RoomEvents.once(`${entity}-subscribed-${id}`, function (err) {
|
RoomEvents.once(`${entity}-subscribed-${id}`, function (err) {
|
||||||
// only allow the client to join when all the relevant channels have subscribed
|
// only allow the client to join when all the relevant channels have subscribed
|
||||||
|
if (err) {
|
||||||
|
OError.tag(err, 'error joining', { entity, id })
|
||||||
|
return callback(err)
|
||||||
|
}
|
||||||
logger.log(
|
logger.log(
|
||||||
{ client: client.id, entity, id, beforeCount },
|
{ client: client.id, entity, id, beforeCount },
|
||||||
'client joined new room and subscribed to channel'
|
'client joined new room and subscribed to channel'
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
const OError = require('@overleaf/o-error')
|
||||||
const { EventEmitter } = require('events')
|
const { EventEmitter } = require('events')
|
||||||
|
|
||||||
module.exports = function (io, sessionStore, cookieParser, cookieName) {
|
module.exports = function (io, sessionStore, cookieParser, cookieName) {
|
||||||
@@ -17,6 +18,9 @@ module.exports = function (io, sessionStore, cookieParser, cookieName) {
|
|||||||
}
|
}
|
||||||
sessionStore.get(sessionId, function (error, session) {
|
sessionStore.get(sessionId, function (error, session) {
|
||||||
if (error) {
|
if (error) {
|
||||||
|
OError.tag(error, 'error getting session from sessionStore', {
|
||||||
|
sessionId
|
||||||
|
})
|
||||||
return next(error, socket)
|
return next(error, socket)
|
||||||
}
|
}
|
||||||
if (!session) {
|
if (!session) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
camelcase,
|
camelcase,
|
||||||
*/
|
*/
|
||||||
const request = require('request')
|
const request = require('request')
|
||||||
|
const OError = require('@overleaf/o-error')
|
||||||
const settings = require('settings-sharelatex')
|
const settings = require('settings-sharelatex')
|
||||||
const logger = require('logger-sharelatex')
|
const logger = require('logger-sharelatex')
|
||||||
const { CodedError } = require('./Errors')
|
const { CodedError } = require('./Errors')
|
||||||
@@ -30,6 +31,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
function (error, response, data) {
|
function (error, response, data) {
|
||||||
if (error) {
|
if (error) {
|
||||||
|
OError.tag(error, 'join project request failed')
|
||||||
return callback(error)
|
return callback(error)
|
||||||
}
|
}
|
||||||
let err
|
let err
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/* eslint-disable
|
/* eslint-disable
|
||||||
camelcase,
|
camelcase,
|
||||||
*/
|
*/
|
||||||
|
const OError = require('@overleaf/o-error')
|
||||||
const logger = require('logger-sharelatex')
|
const logger = require('logger-sharelatex')
|
||||||
const metrics = require('metrics-sharelatex')
|
const metrics = require('metrics-sharelatex')
|
||||||
const WebApiManager = require('./WebApiManager')
|
const WebApiManager = require('./WebApiManager')
|
||||||
@@ -91,7 +92,14 @@ module.exports = WebsocketController = {
|
|||||||
client.publicId,
|
client.publicId,
|
||||||
user,
|
user,
|
||||||
null,
|
null,
|
||||||
function () {}
|
function (err) {
|
||||||
|
if (err) {
|
||||||
|
logger.warn(
|
||||||
|
{ err, project_id, user_id, client_id: client.id },
|
||||||
|
'background cursor update failed'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -229,17 +237,7 @@ module.exports = WebsocketController = {
|
|||||||
try {
|
try {
|
||||||
line = encodeForWebsockets(line)
|
line = encodeForWebsockets(line)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.err(
|
OError.tag(err, 'error encoding line uri component', { line })
|
||||||
{
|
|
||||||
err,
|
|
||||||
project_id,
|
|
||||||
doc_id,
|
|
||||||
fromVersion,
|
|
||||||
line,
|
|
||||||
client_id: client.id
|
|
||||||
},
|
|
||||||
'error encoding line uri component'
|
|
||||||
)
|
|
||||||
return callback(err)
|
return callback(err)
|
||||||
}
|
}
|
||||||
escapedLines.push(line)
|
escapedLines.push(line)
|
||||||
@@ -260,17 +258,9 @@ module.exports = WebsocketController = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.err(
|
OError.tag(err, 'error encoding range uri component', {
|
||||||
{
|
ranges
|
||||||
err,
|
})
|
||||||
project_id,
|
|
||||||
doc_id,
|
|
||||||
fromVersion,
|
|
||||||
ranges,
|
|
||||||
client_id: client.id
|
|
||||||
},
|
|
||||||
'error encoding range uri component'
|
|
||||||
)
|
|
||||||
return callback(err)
|
return callback(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -538,16 +528,9 @@ module.exports = WebsocketController = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
logger.error(
|
OError.tag(error, 'document was not available for update', {
|
||||||
{
|
version: update.v
|
||||||
err: error,
|
})
|
||||||
project_id,
|
|
||||||
doc_id,
|
|
||||||
client_id: client.id,
|
|
||||||
version: update.v
|
|
||||||
},
|
|
||||||
'document was not available for update'
|
|
||||||
)
|
|
||||||
client.disconnect()
|
client.disconnect()
|
||||||
}
|
}
|
||||||
callback(error)
|
callback(error)
|
||||||
|
|||||||
@@ -1464,8 +1464,8 @@ describe('WebsocketController', function () {
|
|||||||
return this.client.disconnect.called.should.equal(true)
|
return this.client.disconnect.called.should.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should log an error', function () {
|
it('should not log an error', function () {
|
||||||
return this.logger.error.called.should.equal(true)
|
return this.logger.error.called.should.equal(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
return it('should call the callback with the error', function () {
|
return it('should call the callback with the error', function () {
|
||||||
|
|||||||
Reference in New Issue
Block a user