mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-07 20:31:06 -05:00
Merge pull request #78 from overleaf/spd-web-ratelimit
Generate retryable error when hitting rate limits in web
This commit is contained in:
commit
b6a7a0ab4c
6 changed files with 54 additions and 7 deletions
10
services/real-time/app/coffee/Errors.coffee
Normal file
10
services/real-time/app/coffee/Errors.coffee
Normal file
|
@ -0,0 +1,10 @@
|
|||
CodedError = (message, code) ->
|
||||
error = new Error(message)
|
||||
error.name = "CodedError"
|
||||
error.code = code
|
||||
error.__proto__ = CodedError.prototype
|
||||
return error
|
||||
CodedError.prototype.__proto__ = Error.prototype
|
||||
|
||||
module.exports = Errors =
|
||||
CodedError: CodedError
|
|
@ -21,6 +21,9 @@ module.exports = Router =
|
|||
attrs[key] = value
|
||||
attrs.client_id = client.id
|
||||
attrs.err = error
|
||||
if error.name == "CodedError"
|
||||
logger.warn attrs, error.message, code: error.code
|
||||
return callback {message: error.message, code: error.code}
|
||||
if error.message in ["not authorized", "doc updater could not load requested ops", "no project_id found on client"]
|
||||
logger.warn attrs, error.message
|
||||
return callback {message: error.message}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
request = require "request"
|
||||
settings = require "settings-sharelatex"
|
||||
logger = require "logger-sharelatex"
|
||||
{ CodedError } = require "./Errors"
|
||||
|
||||
module.exports = WebApiManager =
|
||||
joinProject: (project_id, user, callback = (error, project, privilegeLevel) ->) ->
|
||||
|
@ -24,7 +25,10 @@ module.exports = WebApiManager =
|
|||
return callback(error) if error?
|
||||
if 200 <= response.statusCode < 300
|
||||
callback null, data?.project, data?.privilegeLevel
|
||||
else if response.statusCode == 429
|
||||
logger.log(project_id, user_id, "rate-limit hit when joining project")
|
||||
callback(new CodedError("rate-limit hit when joining project", "TooManyRequests"))
|
||||
else
|
||||
err = new Error("non-success status code from web: #{response.statusCode}")
|
||||
logger.error {err, project_id, user_id}, "error accessing web api"
|
||||
logger.error {err, project_id, user_id}, "error accessing web api"
|
||||
callback err
|
||||
|
|
|
@ -89,3 +89,20 @@ describe "joinProject", ->
|
|||
RealTimeClient.getConnectedClient @client.socket.sessionid, (error, client) =>
|
||||
expect(@project_id in client.rooms).to.equal false
|
||||
done()
|
||||
|
||||
describe "when over rate limit", ->
|
||||
before (done) ->
|
||||
async.series [
|
||||
(cb) =>
|
||||
@client = RealTimeClient.connect()
|
||||
@client.on "connectionAccepted", cb
|
||||
|
||||
(cb) =>
|
||||
@client.emit "joinProject", project_id: 'rate-limited', (@error) =>
|
||||
cb()
|
||||
], done
|
||||
|
||||
it "should return a TooManyRequests error code", ->
|
||||
@error.message.should.equal "rate-limit hit when joining project"
|
||||
@error.code.should.equal "TooManyRequests"
|
||||
|
||||
|
|
|
@ -19,12 +19,15 @@ module.exports = MockWebServer =
|
|||
joinProjectRequest: (req, res, next) ->
|
||||
{project_id} = req.params
|
||||
{user_id} = req.query
|
||||
MockWebServer.joinProject project_id, user_id, (error, project, privilegeLevel) ->
|
||||
return next(error) if error?
|
||||
res.json {
|
||||
project: project
|
||||
privilegeLevel: privilegeLevel
|
||||
}
|
||||
if project_id == 'rate-limited'
|
||||
res.status(429).send()
|
||||
else
|
||||
MockWebServer.joinProject project_id, user_id, (error, project, privilegeLevel) ->
|
||||
return next(error) if error?
|
||||
res.json {
|
||||
project: project
|
||||
privilegeLevel: privilegeLevel
|
||||
}
|
||||
|
||||
running: false
|
||||
run: (callback = (error) ->) ->
|
||||
|
|
|
@ -3,6 +3,7 @@ should = chai.should()
|
|||
sinon = require("sinon")
|
||||
modulePath = "../../../app/js/WebApiManager.js"
|
||||
SandboxedModule = require('sandboxed-module')
|
||||
{ CodedError } = require('../../../app/js/Errors')
|
||||
|
||||
describe 'WebApiManager', ->
|
||||
beforeEach ->
|
||||
|
@ -61,3 +62,12 @@ describe 'WebApiManager', ->
|
|||
.calledWith(new Error("non-success code from web: 500"))
|
||||
.should.equal true
|
||||
|
||||
describe "when the project is over its rate limit", ->
|
||||
beforeEach ->
|
||||
@request.post = sinon.stub().callsArgWith(1, null, {statusCode: 429}, null)
|
||||
@WebApiManager.joinProject @project_id, @user_id, @callback
|
||||
|
||||
it "should call the callback with a TooManyRequests error code", ->
|
||||
@callback
|
||||
.calledWith(new CodedError("rate-limit hit when joining project", "TooManyRequests"))
|
||||
.should.equal true
|
||||
|
|
Loading…
Reference in a new issue