Просмотр исходного кода

Merge pull request #8729 from overleaf/bg-return-file-too-large

[document-updater] return 413 error when doc is too large

GitOrigin-RevId: d66300c78bea4071f29044be160929dba782b728
Brian Gough 4 лет назад
Родитель
Сommit
0c63515de6

+ 2 - 0
services/document-updater/app.js

@@ -185,6 +185,8 @@ app.use((error, req, res, next) => {
     return res.sendStatus(404)
   } else if (error instanceof Errors.OpRangeNotAvailableError) {
     return res.sendStatus(422) // Unprocessable Entity
+  } else if (error instanceof Errors.FileTooLargeError) {
+    return res.sendStatus(413)
   } else if (error.statusCode === 413) {
     return res.status(413).send('request entity too large')
   } else {

+ 9 - 0
services/document-updater/app/js/Errors.js

@@ -37,9 +37,18 @@ function DeleteMismatchError(message) {
 }
 DeleteMismatchError.prototype.__proto__ = Error.prototype
 
+function FileTooLargeError(message) {
+  const error = new Error(message)
+  error.name = 'FileTooLargeError'
+  error.__proto__ = FileTooLargeError.prototype
+  return error
+}
+FileTooLargeError.prototype.__proto__ = Error.prototype
+
 module.exports = Errors = {
   NotFoundError,
   OpRangeNotAvailableError,
   ProjectStateChangedError,
   DeleteMismatchError,
+  FileTooLargeError,
 }

+ 8 - 0
services/document-updater/app/js/PersistenceManager.js

@@ -104,6 +104,10 @@ function getDoc(projectId, docId, options = {}, _callback) {
       )
     } else if (res.statusCode === 404) {
       callback(new Errors.NotFoundError(`doc not not found: ${urlPath}`))
+    } else if (res.statusCode === 413) {
+      callback(
+        new Errors.FileTooLargeError(`doc exceeds maximum size: ${urlPath}`)
+      )
     } else {
       callback(
         new Error(`error accessing web API: ${urlPath} ${res.statusCode}`)
@@ -158,6 +162,10 @@ function setDoc(
         callback(null)
       } else if (res.statusCode === 404) {
         callback(new Errors.NotFoundError(`doc not not found: ${urlPath}`))
+      } else if (res.statusCode === 413) {
+        callback(
+          new Errors.FileTooLargeError(`doc exceeds maximum size: ${urlPath}`)
+        )
       } else {
         callback(
           new Error(`error accessing web API: ${urlPath} ${res.statusCode}`)

+ 59 - 0
services/document-updater/test/unit/js/PersistenceManager/PersistenceManagerTests.js

@@ -206,6 +206,33 @@ describe('PersistenceManager', function () {
       })
     })
 
+    describe('when the request returns 413', function () {
+      beforeEach(function () {
+        this.request.callsArgWith(1, null, { statusCode: 413 }, '')
+        this.PersistenceManager.getDoc(
+          this.project_id,
+          this.doc_id,
+          this.callback
+        )
+      })
+
+      it('should return a FileTooLargeError', function () {
+        this.callback
+          .calledWith(sinon.match.instanceOf(Errors.FileTooLargeError))
+          .should.equal(true)
+      })
+
+      it('should time the execution', function () {
+        this.Metrics.Timer.prototype.done.called.should.equal(true)
+      })
+
+      it('should increment the metric', function () {
+        this.Metrics.inc
+          .calledWith('getDoc', 1, { status: 413 })
+          .should.equal(true)
+      })
+    })
+
     describe('when the request returns an error status code', function () {
       beforeEach(function () {
         this.request.callsArgWith(1, null, { statusCode: 500 }, '')
@@ -427,6 +454,38 @@ describe('PersistenceManager', function () {
       })
     })
 
+    describe('when the request returns 413', function () {
+      beforeEach(function () {
+        this.request.callsArgWith(1, null, { statusCode: 413 }, '')
+        this.PersistenceManager.setDoc(
+          this.project_id,
+          this.doc_id,
+          this.lines,
+          this.version,
+          this.ranges,
+          this.lastUpdatedAt,
+          this.lastUpdatedBy,
+          this.callback
+        )
+      })
+
+      it('should return a FileTooLargeError', function () {
+        this.callback
+          .calledWith(sinon.match.instanceOf(Errors.FileTooLargeError))
+          .should.equal(true)
+      })
+
+      it('should time the execution', function () {
+        this.Metrics.Timer.prototype.done.called.should.equal(true)
+      })
+
+      it('should increment the metric', function () {
+        this.Metrics.inc
+          .calledWith('setDoc', 1, { status: 413 })
+          .should.equal(true)
+      })
+    })
+
     describe('when the request returns an error status code', function () {
       beforeEach(function () {
         this.request.callsArgWith(1, null, { statusCode: 500 }, '')