mirror of
https://github.com/overleaf/overleaf.git
synced 2024-09-16 02:52:31 -04:00
Merge pull request #184 from overleaf/jpa-custom-errors
[misc] migrate to custom OErrors
This commit is contained in:
commit
735027a2b7
13 changed files with 190 additions and 100 deletions
|
@ -1,6 +1,8 @@
|
||||||
/* eslint-disable
|
/* eslint-disable
|
||||||
camelcase,
|
camelcase,
|
||||||
*/
|
*/
|
||||||
|
const { NotAuthorizedError } = require('./Errors')
|
||||||
|
|
||||||
let AuthorizationManager
|
let AuthorizationManager
|
||||||
module.exports = AuthorizationManager = {
|
module.exports = AuthorizationManager = {
|
||||||
assertClientCanViewProject(client, callback) {
|
assertClientCanViewProject(client, callback) {
|
||||||
|
@ -23,7 +25,7 @@ module.exports = AuthorizationManager = {
|
||||||
if (allowedLevels.includes(client.ol_context.privilege_level)) {
|
if (allowedLevels.includes(client.ol_context.privilege_level)) {
|
||||||
callback(null)
|
callback(null)
|
||||||
} else {
|
} else {
|
||||||
callback(new Error('not authorized'))
|
callback(new NotAuthorizedError())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -49,7 +51,7 @@ module.exports = AuthorizationManager = {
|
||||||
if (client.ol_context[`doc:${doc_id}`] === 'allowed') {
|
if (client.ol_context[`doc:${doc_id}`] === 'allowed') {
|
||||||
callback(null)
|
callback(null)
|
||||||
} else {
|
} else {
|
||||||
callback(new Error('not authorized'))
|
callback(new NotAuthorizedError())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,12 @@ const _ = require('underscore')
|
||||||
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')
|
||||||
|
const {
|
||||||
|
ClientRequestedMissingOpsError,
|
||||||
|
DocumentUpdaterRequestFailedError,
|
||||||
|
NullBytesInOpError,
|
||||||
|
UpdateTooLargeError
|
||||||
|
} = require('./Errors')
|
||||||
|
|
||||||
const rclient = require('redis-sharelatex').createClient(
|
const rclient = require('redis-sharelatex').createClient(
|
||||||
settings.redis.documentupdater
|
settings.redis.documentupdater
|
||||||
|
@ -42,23 +48,11 @@ const DocumentUpdaterManager = {
|
||||||
body = body || {}
|
body = body || {}
|
||||||
callback(null, body.lines, body.version, body.ranges, body.ops)
|
callback(null, body.lines, body.version, body.ranges, body.ops)
|
||||||
} else if ([404, 422].includes(res.statusCode)) {
|
} else if ([404, 422].includes(res.statusCode)) {
|
||||||
err = new Error('doc updater could not load requested ops')
|
callback(new ClientRequestedMissingOpsError(res.statusCode))
|
||||||
err.statusCode = res.statusCode
|
|
||||||
logger.warn(
|
|
||||||
{ err, project_id, doc_id, url, fromVersion },
|
|
||||||
'doc updater could not load requested ops'
|
|
||||||
)
|
|
||||||
callback(err)
|
|
||||||
} else {
|
} else {
|
||||||
err = new Error(
|
callback(
|
||||||
`doc updater returned a non-success status code: ${res.statusCode}`
|
new DocumentUpdaterRequestFailedError('getDocument', res.statusCode)
|
||||||
)
|
)
|
||||||
err.statusCode = res.statusCode
|
|
||||||
logger.error(
|
|
||||||
{ err, project_id, doc_id, url },
|
|
||||||
`doc updater returned a non-success status code: ${res.statusCode}`
|
|
||||||
)
|
|
||||||
callback(err)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -88,15 +82,12 @@ const DocumentUpdaterManager = {
|
||||||
logger.log({ project_id }, 'deleted project from document updater')
|
logger.log({ project_id }, 'deleted project from document updater')
|
||||||
callback(null)
|
callback(null)
|
||||||
} else {
|
} else {
|
||||||
err = new Error(
|
callback(
|
||||||
`document updater returned a failure status code: ${res.statusCode}`
|
new DocumentUpdaterRequestFailedError(
|
||||||
|
'flushProjectToMongoAndDelete',
|
||||||
|
res.statusCode
|
||||||
|
)
|
||||||
)
|
)
|
||||||
err.statusCode = res.statusCode
|
|
||||||
logger.error(
|
|
||||||
{ err, project_id },
|
|
||||||
`document updater returned failure status code: ${res.statusCode}`
|
|
||||||
)
|
|
||||||
callback(err)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -115,19 +106,12 @@ const DocumentUpdaterManager = {
|
||||||
const jsonChange = JSON.stringify(change)
|
const jsonChange = JSON.stringify(change)
|
||||||
if (jsonChange.indexOf('\u0000') !== -1) {
|
if (jsonChange.indexOf('\u0000') !== -1) {
|
||||||
// memory corruption check
|
// memory corruption check
|
||||||
const error = new Error('null bytes found in op')
|
return callback(new NullBytesInOpError(jsonChange))
|
||||||
logger.error(
|
|
||||||
{ err: error, project_id, doc_id, jsonChange },
|
|
||||||
error.message
|
|
||||||
)
|
|
||||||
return callback(error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateSize = jsonChange.length
|
const updateSize = jsonChange.length
|
||||||
if (updateSize > settings.maxUpdateSize) {
|
if (updateSize > settings.maxUpdateSize) {
|
||||||
const error = new Error('update is too large')
|
return callback(new UpdateTooLargeError(updateSize))
|
||||||
error.updateSize = updateSize
|
|
||||||
return callback(error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// record metric for each update added to queue
|
// record metric for each update added to queue
|
||||||
|
|
|
@ -1,9 +1,103 @@
|
||||||
class CodedError extends Error {
|
const OError = require('@overleaf/o-error')
|
||||||
constructor(message, code) {
|
|
||||||
super(message)
|
class ClientRequestedMissingOpsError extends OError {
|
||||||
this.name = this.constructor.name
|
constructor(statusCode) {
|
||||||
this.code = code
|
super('doc updater could not load requested ops', {
|
||||||
|
statusCode
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { CodedError }
|
class CodedError extends OError {
|
||||||
|
constructor(message, code) {
|
||||||
|
super(message, { code })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CorruptedJoinProjectResponseError extends OError {
|
||||||
|
constructor() {
|
||||||
|
super('no data returned from joinProject request')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DataTooLargeToParseError extends OError {
|
||||||
|
constructor(data) {
|
||||||
|
super('data too large to parse', {
|
||||||
|
head: data.slice(0, 1024),
|
||||||
|
length: data.length
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DocumentUpdaterRequestFailedError extends OError {
|
||||||
|
constructor(action, statusCode) {
|
||||||
|
super('doc updater returned a non-success status code', {
|
||||||
|
action,
|
||||||
|
statusCode
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class JoinLeaveEpochMismatchError extends OError {
|
||||||
|
constructor() {
|
||||||
|
super('joinLeaveEpoch mismatch')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MissingSessionError extends OError {
|
||||||
|
constructor() {
|
||||||
|
super('could not look up session by key')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NotAuthorizedError extends OError {
|
||||||
|
constructor() {
|
||||||
|
super('not authorized')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NotJoinedError extends OError {
|
||||||
|
constructor() {
|
||||||
|
super('no project_id found on client')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class NullBytesInOpError extends OError {
|
||||||
|
constructor(jsonChange) {
|
||||||
|
super('null bytes found in op', { jsonChange })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UnexpectedArgumentsError extends OError {
|
||||||
|
constructor() {
|
||||||
|
super('unexpected arguments')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UpdateTooLargeError extends OError {
|
||||||
|
constructor(updateSize) {
|
||||||
|
super('update is too large', { updateSize })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class WebApiRequestFailedError extends OError {
|
||||||
|
constructor(statusCode) {
|
||||||
|
super('non-success status code from web', { statusCode })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
CodedError,
|
||||||
|
CorruptedJoinProjectResponseError,
|
||||||
|
ClientRequestedMissingOpsError,
|
||||||
|
DataTooLargeToParseError,
|
||||||
|
DocumentUpdaterRequestFailedError,
|
||||||
|
JoinLeaveEpochMismatchError,
|
||||||
|
MissingSessionError,
|
||||||
|
NotAuthorizedError,
|
||||||
|
NotJoinedError,
|
||||||
|
NullBytesInOpError,
|
||||||
|
UnexpectedArgumentsError,
|
||||||
|
UpdateTooLargeError,
|
||||||
|
WebApiRequestFailedError
|
||||||
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ const HttpController = require('./HttpController')
|
||||||
const HttpApiController = require('./HttpApiController')
|
const HttpApiController = require('./HttpApiController')
|
||||||
const bodyParser = require('body-parser')
|
const bodyParser = require('body-parser')
|
||||||
const base64id = require('base64id')
|
const base64id = require('base64id')
|
||||||
|
const { UnexpectedArgumentsError } = require('./Errors')
|
||||||
|
|
||||||
const basicAuth = require('basic-auth-connect')
|
const basicAuth = require('basic-auth-connect')
|
||||||
const httpAuth = basicAuth(function (user, pass) {
|
const httpAuth = basicAuth(function (user, pass) {
|
||||||
|
@ -33,8 +34,8 @@ module.exports = Router = {
|
||||||
attrs.client_id = client.id
|
attrs.client_id = client.id
|
||||||
attrs.err = error
|
attrs.err = error
|
||||||
if (error.name === 'CodedError') {
|
if (error.name === 'CodedError') {
|
||||||
logger.warn(attrs, error.message, { code: error.code })
|
logger.warn(attrs, error.message)
|
||||||
const serializedError = { message: error.message, code: error.code }
|
const serializedError = { message: error.message, code: error.info.code }
|
||||||
callback(serializedError)
|
callback(serializedError)
|
||||||
} else if (error.message === 'unexpected arguments') {
|
} else if (error.message === 'unexpected arguments') {
|
||||||
// the payload might be very large, put it on level info
|
// the payload might be very large, put it on level info
|
||||||
|
@ -64,7 +65,7 @@ module.exports = Router = {
|
||||||
},
|
},
|
||||||
|
|
||||||
_handleInvalidArguments(client, method, args) {
|
_handleInvalidArguments(client, method, args) {
|
||||||
const error = new Error('unexpected arguments')
|
const error = new UnexpectedArgumentsError()
|
||||||
let callback = args[args.length - 1]
|
let callback = args[args.length - 1]
|
||||||
if (typeof callback !== 'function') {
|
if (typeof callback !== 'function') {
|
||||||
callback = function () {}
|
callback = function () {}
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
const Settings = require('settings-sharelatex')
|
const Settings = require('settings-sharelatex')
|
||||||
const logger = require('logger-sharelatex')
|
const { DataTooLargeToParseError } = require('./Errors')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
parse(data, callback) {
|
parse(data, callback) {
|
||||||
if (data.length > Settings.maxUpdateSize) {
|
if (data.length > Settings.maxUpdateSize) {
|
||||||
logger.error(
|
return callback(new DataTooLargeToParseError(data))
|
||||||
{ head: data.slice(0, 1024), length: data.length },
|
|
||||||
'data too large to parse'
|
|
||||||
)
|
|
||||||
return callback(new Error('data too large to parse'))
|
|
||||||
}
|
}
|
||||||
let parsed
|
let parsed
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
const { EventEmitter } = require('events')
|
const { EventEmitter } = require('events')
|
||||||
|
const { MissingSessionError } = require('./Errors')
|
||||||
|
|
||||||
module.exports = function (io, sessionStore, cookieParser, cookieName) {
|
module.exports = function (io, sessionStore, cookieParser, cookieName) {
|
||||||
const missingSessionError = new Error('could not look up session by key')
|
const missingSessionError = new MissingSessionError()
|
||||||
|
|
||||||
const sessionSockets = new EventEmitter()
|
const sessionSockets = new EventEmitter()
|
||||||
function next(error, socket, session) {
|
function next(error, socket, session) {
|
||||||
|
|
|
@ -4,7 +4,11 @@
|
||||||
const request = require('request')
|
const request = require('request')
|
||||||
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,
|
||||||
|
CorruptedJoinProjectResponseError,
|
||||||
|
WebApiRequestFailedError
|
||||||
|
} = require('./Errors')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
joinProject(project_id, user, callback) {
|
joinProject(project_id, user, callback) {
|
||||||
|
@ -32,15 +36,9 @@ module.exports = {
|
||||||
if (error) {
|
if (error) {
|
||||||
return callback(error)
|
return callback(error)
|
||||||
}
|
}
|
||||||
let err
|
|
||||||
if (response.statusCode >= 200 && response.statusCode < 300) {
|
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||||
if (!(data && data.project)) {
|
if (!(data && data.project)) {
|
||||||
err = new Error('no data returned from joinProject request')
|
return callback(new CorruptedJoinProjectResponseError())
|
||||||
logger.error(
|
|
||||||
{ err, project_id, user_id },
|
|
||||||
'error accessing web api'
|
|
||||||
)
|
|
||||||
return callback(err)
|
|
||||||
}
|
}
|
||||||
callback(
|
callback(
|
||||||
null,
|
null,
|
||||||
|
@ -57,11 +55,7 @@ module.exports = {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
err = new Error(
|
callback(new WebApiRequestFailedError(response.statusCode))
|
||||||
`non-success status code from web: ${response.statusCode}`
|
|
||||||
)
|
|
||||||
logger.error({ err, project_id, user_id }, 'error accessing web api')
|
|
||||||
callback(err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,6 +9,11 @@ const DocumentUpdaterManager = require('./DocumentUpdaterManager')
|
||||||
const ConnectedUsersManager = require('./ConnectedUsersManager')
|
const ConnectedUsersManager = require('./ConnectedUsersManager')
|
||||||
const WebsocketLoadBalancer = require('./WebsocketLoadBalancer')
|
const WebsocketLoadBalancer = require('./WebsocketLoadBalancer')
|
||||||
const RoomManager = require('./RoomManager')
|
const RoomManager = require('./RoomManager')
|
||||||
|
const {
|
||||||
|
JoinLeaveEpochMismatchError,
|
||||||
|
NotAuthorizedError,
|
||||||
|
NotJoinedError
|
||||||
|
} = require('./Errors')
|
||||||
|
|
||||||
let WebsocketController
|
let WebsocketController
|
||||||
module.exports = WebsocketController = {
|
module.exports = WebsocketController = {
|
||||||
|
@ -48,12 +53,7 @@ module.exports = WebsocketController = {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!privilegeLevel) {
|
if (!privilegeLevel) {
|
||||||
const err = new Error('not authorized')
|
return callback(new NotAuthorizedError())
|
||||||
logger.warn(
|
|
||||||
{ err, project_id, user_id, client_id: client.id },
|
|
||||||
'user is not authorized to join project'
|
|
||||||
)
|
|
||||||
return callback(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
client.ol_context = {}
|
client.ol_context = {}
|
||||||
|
@ -162,7 +162,7 @@ module.exports = WebsocketController = {
|
||||||
metrics.inc('editor.join-doc')
|
metrics.inc('editor.join-doc')
|
||||||
const { project_id, user_id, is_restricted_user } = client.ol_context
|
const { project_id, user_id, is_restricted_user } = client.ol_context
|
||||||
if (!project_id) {
|
if (!project_id) {
|
||||||
return callback(new Error('no project_id found on client'))
|
return callback(new NotJoinedError())
|
||||||
}
|
}
|
||||||
logger.log(
|
logger.log(
|
||||||
{ user_id, project_id, doc_id, fromVersion, client_id: client.id },
|
{ user_id, project_id, doc_id, fromVersion, client_id: client.id },
|
||||||
|
@ -184,7 +184,7 @@ module.exports = WebsocketController = {
|
||||||
}
|
}
|
||||||
if (joinLeaveEpoch !== client.joinLeaveEpoch) {
|
if (joinLeaveEpoch !== client.joinLeaveEpoch) {
|
||||||
// another joinDoc or leaveDoc rpc overtook us
|
// another joinDoc or leaveDoc rpc overtook us
|
||||||
return callback(new Error('joinLeaveEpoch mismatch'))
|
return callback(new JoinLeaveEpochMismatchError())
|
||||||
}
|
}
|
||||||
// ensure the per-doc applied-ops channel is subscribed before sending the
|
// ensure the per-doc applied-ops channel is subscribed before sending the
|
||||||
// doc to the client, so that no events are missed.
|
// doc to the client, so that no events are missed.
|
||||||
|
@ -428,7 +428,7 @@ module.exports = WebsocketController = {
|
||||||
return callback(null, [])
|
return callback(null, [])
|
||||||
}
|
}
|
||||||
if (!project_id) {
|
if (!project_id) {
|
||||||
return callback(new Error('no project_id found on client'))
|
return callback(new NotJoinedError())
|
||||||
}
|
}
|
||||||
logger.log(
|
logger.log(
|
||||||
{ user_id, project_id, client_id: client.id },
|
{ user_id, project_id, client_id: client.id },
|
||||||
|
@ -463,7 +463,7 @@ module.exports = WebsocketController = {
|
||||||
// client may have disconnected, but we can submit their update to doc-updater anyways.
|
// client may have disconnected, but we can submit their update to doc-updater anyways.
|
||||||
const { user_id, project_id } = client.ol_context
|
const { user_id, project_id } = client.ol_context
|
||||||
if (!project_id) {
|
if (!project_id) {
|
||||||
return callback(new Error('no project_id found on client'))
|
return callback(new NotJoinedError())
|
||||||
}
|
}
|
||||||
|
|
||||||
WebsocketController._assertClientCanApplyUpdate(
|
WebsocketController._assertClientCanApplyUpdate(
|
||||||
|
@ -509,7 +509,7 @@ module.exports = WebsocketController = {
|
||||||
function (error) {
|
function (error) {
|
||||||
if ((error && error.message) === 'update is too large') {
|
if ((error && error.message) === 'update is too large') {
|
||||||
metrics.inc('update_too_large')
|
metrics.inc('update_too_large')
|
||||||
const { updateSize } = error
|
const { updateSize } = error.info
|
||||||
logger.warn(
|
logger.warn(
|
||||||
{ user_id, project_id, doc_id, updateSize },
|
{ user_id, project_id, doc_id, updateSize },
|
||||||
'update is too large'
|
'update is too large'
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
"format:fix": "node_modules/.bin/prettier-eslint $PWD'/**/*.js' --write"
|
"format:fix": "node_modules/.bin/prettier-eslint $PWD'/**/*.js' --write"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@overleaf/o-error": "^3.0.0",
|
||||||
"async": "^0.9.0",
|
"async": "^0.9.0",
|
||||||
"base64id": "0.1.0",
|
"base64id": "0.1.0",
|
||||||
"basic-auth-connect": "^1.0.0",
|
"basic-auth-connect": "^1.0.0",
|
||||||
|
|
|
@ -136,14 +136,16 @@ describe('DocumentUpdaterManager', function () {
|
||||||
|
|
||||||
return it('should return the callback with an error', function () {
|
return it('should return the callback with an error', function () {
|
||||||
this.callback.called.should.equal(true)
|
this.callback.called.should.equal(true)
|
||||||
const err = this.callback.getCall(0).args[0]
|
this.callback
|
||||||
err.should.have.property('statusCode', statusCode)
|
.calledWith(
|
||||||
err.should.have.property(
|
sinon.match({
|
||||||
'message',
|
message: 'doc updater could not load requested ops',
|
||||||
'doc updater could not load requested ops'
|
info: { statusCode }
|
||||||
)
|
})
|
||||||
|
)
|
||||||
|
.should.equal(true)
|
||||||
this.logger.error.called.should.equal(false)
|
this.logger.error.called.should.equal(false)
|
||||||
return this.logger.warn.called.should.equal(true)
|
this.logger.warn.called.should.equal(false)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
@ -163,13 +165,18 @@ describe('DocumentUpdaterManager', function () {
|
||||||
|
|
||||||
return it('should return the callback with an error', function () {
|
return it('should return the callback with an error', function () {
|
||||||
this.callback.called.should.equal(true)
|
this.callback.called.should.equal(true)
|
||||||
const err = this.callback.getCall(0).args[0]
|
this.callback
|
||||||
err.should.have.property('statusCode', 500)
|
.calledWith(
|
||||||
err.should.have.property(
|
sinon.match({
|
||||||
'message',
|
message: 'doc updater returned a non-success status code',
|
||||||
'doc updater returned a non-success status code: 500'
|
info: {
|
||||||
)
|
action: 'getDocument',
|
||||||
return this.logger.error.called.should.equal(true)
|
statusCode: 500
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.should.equal(true)
|
||||||
|
this.logger.error.called.should.equal(false)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -234,12 +241,17 @@ describe('DocumentUpdaterManager', function () {
|
||||||
|
|
||||||
return it('should return the callback with an error', function () {
|
return it('should return the callback with an error', function () {
|
||||||
this.callback.called.should.equal(true)
|
this.callback.called.should.equal(true)
|
||||||
const err = this.callback.getCall(0).args[0]
|
this.callback
|
||||||
err.should.have.property('statusCode', 500)
|
.calledWith(
|
||||||
return err.should.have.property(
|
sinon.match({
|
||||||
'message',
|
message: 'doc updater returned a non-success status code',
|
||||||
'document updater returned a failure status code: 500'
|
info: {
|
||||||
)
|
action: 'flushProjectToMongoAndDelete',
|
||||||
|
statusCode: 500
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.should.equal(true)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -346,7 +358,7 @@ describe('DocumentUpdaterManager', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should add the size to the error', function () {
|
it('should add the size to the error', function () {
|
||||||
return this.callback.args[0][0].updateSize.should.equal(7782422)
|
return this.callback.args[0][0].info.updateSize.should.equal(7782422)
|
||||||
})
|
})
|
||||||
|
|
||||||
return it('should not push the change onto the pending-updates-list queue', function () {
|
return it('should not push the change onto the pending-updates-list queue', function () {
|
||||||
|
|
|
@ -50,7 +50,7 @@ describe('SafeJsonParse', function () {
|
||||||
const data = `{\"foo\": \"${big_blob}\"}`
|
const data = `{\"foo\": \"${big_blob}\"}`
|
||||||
this.Settings.maxUpdateSize = 2 * 1024
|
this.Settings.maxUpdateSize = 2 * 1024
|
||||||
return this.SafeJsonParse.parse(data, (error, parsed) => {
|
return this.SafeJsonParse.parse(data, (error, parsed) => {
|
||||||
this.logger.error.called.should.equal(true)
|
this.logger.error.called.should.equal(false)
|
||||||
expect(error).to.exist
|
expect(error).to.exist
|
||||||
return done()
|
return done()
|
||||||
})
|
})
|
||||||
|
|
|
@ -106,7 +106,10 @@ describe('WebApiManager', function () {
|
||||||
return it('should call the callback with an error', function () {
|
return it('should call the callback with an error', function () {
|
||||||
return this.callback
|
return this.callback
|
||||||
.calledWith(
|
.calledWith(
|
||||||
sinon.match({ message: 'non-success status code from web: 500' })
|
sinon.match({
|
||||||
|
message: 'non-success status code from web',
|
||||||
|
info: { statusCode: 500 }
|
||||||
|
})
|
||||||
)
|
)
|
||||||
.should.equal(true)
|
.should.equal(true)
|
||||||
})
|
})
|
||||||
|
@ -152,7 +155,9 @@ describe('WebApiManager', function () {
|
||||||
.calledWith(
|
.calledWith(
|
||||||
sinon.match({
|
sinon.match({
|
||||||
message: 'rate-limit hit when joining project',
|
message: 'rate-limit hit when joining project',
|
||||||
code: 'TooManyRequests'
|
info: {
|
||||||
|
code: 'TooManyRequests'
|
||||||
|
}
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.should.equal(true)
|
.should.equal(true)
|
||||||
|
|
|
@ -19,6 +19,7 @@ const { expect } = chai
|
||||||
const modulePath = '../../../app/js/WebsocketController.js'
|
const modulePath = '../../../app/js/WebsocketController.js'
|
||||||
const SandboxedModule = require('sandboxed-module')
|
const SandboxedModule = require('sandboxed-module')
|
||||||
const tk = require('timekeeper')
|
const tk = require('timekeeper')
|
||||||
|
const { UpdateTooLargeError } = require('../../../app/js/Errors')
|
||||||
|
|
||||||
describe('WebsocketController', function () {
|
describe('WebsocketController', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
|
@ -1507,8 +1508,7 @@ describe('WebsocketController', function () {
|
||||||
this.client.emit = sinon.stub()
|
this.client.emit = sinon.stub()
|
||||||
this.client.ol_context.user_id = this.user_id
|
this.client.ol_context.user_id = this.user_id
|
||||||
this.client.ol_context.project_id = this.project_id
|
this.client.ol_context.project_id = this.project_id
|
||||||
const error = new Error('update is too large')
|
const error = new UpdateTooLargeError(7372835)
|
||||||
error.updateSize = 7372835
|
|
||||||
this.DocumentUpdaterManager.queueChange = sinon
|
this.DocumentUpdaterManager.queueChange = sinon
|
||||||
.stub()
|
.stub()
|
||||||
.callsArgWith(3, error)
|
.callsArgWith(3, error)
|
||||||
|
|
Loading…
Reference in a new issue