ErrorController.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. let ErrorController
  2. const Errors = require('./Errors')
  3. const logger = require('@overleaf/logger')
  4. const SessionManager = require('../Authentication/SessionManager')
  5. const SamlLogHandler = require('../SamlLog/SamlLogHandler')
  6. const HttpErrorHandler = require('./HttpErrorHandler')
  7. const { plainTextResponse } = require('../../infrastructure/Response')
  8. module.exports = ErrorController = {
  9. notFound(req, res) {
  10. res.status(404)
  11. res.render('general/404', { title: 'page_not_found' })
  12. },
  13. forbidden(req, res) {
  14. res.status(403)
  15. res.render('user/restricted')
  16. },
  17. serverError(req, res) {
  18. res.status(500)
  19. res.render('general/500', { title: 'Server Error' })
  20. },
  21. handleError(error, req, res, next) {
  22. const shouldSendErrorResponse = !res.headersSent
  23. const user = SessionManager.getSessionUser(req.session)
  24. // log errors related to SAML flow
  25. if (req.session && req.session.saml) {
  26. SamlLogHandler.log(req, { error })
  27. }
  28. if (error.code === 'EBADCSRFTOKEN') {
  29. logger.warn(
  30. { err: error, url: req.url, method: req.method, user },
  31. 'invalid csrf'
  32. )
  33. if (shouldSendErrorResponse) {
  34. res.sendStatus(403)
  35. }
  36. } else if (error instanceof Errors.NotFoundError) {
  37. logger.warn({ err: error, url: req.url }, 'not found error')
  38. if (shouldSendErrorResponse) {
  39. ErrorController.notFound(req, res)
  40. }
  41. } else if (
  42. error instanceof URIError &&
  43. error.message.match(/^Failed to decode param/)
  44. ) {
  45. logger.warn({ err: error, url: req.url }, 'Express URIError')
  46. if (shouldSendErrorResponse) {
  47. res.status(400)
  48. res.render('general/500', { title: 'Invalid Error' })
  49. }
  50. } else if (error instanceof Errors.ForbiddenError) {
  51. logger.error({ err: error }, 'forbidden error')
  52. if (shouldSendErrorResponse) {
  53. ErrorController.forbidden(req, res)
  54. }
  55. } else if (error instanceof Errors.TooManyRequestsError) {
  56. logger.warn({ err: error, url: req.url }, 'too many requests error')
  57. if (shouldSendErrorResponse) {
  58. res.sendStatus(429)
  59. }
  60. } else if (error instanceof Errors.InvalidError) {
  61. logger.warn({ err: error, url: req.url }, 'invalid error')
  62. if (shouldSendErrorResponse) {
  63. res.status(400)
  64. plainTextResponse(res, error.message)
  65. }
  66. } else if (error instanceof Errors.InvalidNameError) {
  67. logger.warn({ err: error, url: req.url }, 'invalid name error')
  68. if (shouldSendErrorResponse) {
  69. res.status(400)
  70. plainTextResponse(res, error.message)
  71. }
  72. } else if (error instanceof Errors.SAMLSessionDataMissing) {
  73. logger.warn(
  74. { err: error, url: req.url },
  75. 'missing SAML session data error'
  76. )
  77. if (shouldSendErrorResponse) {
  78. HttpErrorHandler.badRequest(req, res, error.message)
  79. }
  80. } else {
  81. logger.error(
  82. { err: error, url: req.url, method: req.method, user },
  83. 'error passed to top level next middleware'
  84. )
  85. if (shouldSendErrorResponse) {
  86. ErrorController.serverError(req, res)
  87. }
  88. }
  89. if (!shouldSendErrorResponse) {
  90. // Pass the error to the default Express error handler, which will close
  91. // the connection.
  92. next(error)
  93. }
  94. },
  95. handleApiError(error, req, res, next) {
  96. if (error instanceof Errors.NotFoundError) {
  97. logger.warn({ err: error, url: req.url }, 'not found error')
  98. res.sendStatus(404)
  99. } else if (
  100. error instanceof URIError &&
  101. error.message.match(/^Failed to decode param/)
  102. ) {
  103. logger.warn({ err: error, url: req.url }, 'Express URIError')
  104. res.sendStatus(400)
  105. } else {
  106. logger.error(
  107. { err: error, url: req.url, method: req.method },
  108. 'error passed to top level next middleware'
  109. )
  110. res.sendStatus(500)
  111. }
  112. },
  113. }