server.js 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import Metrics from '@overleaf/metrics'
  2. import logger from '@overleaf/logger'
  3. import OError from '@overleaf/o-error'
  4. import express from 'express'
  5. import bodyParser from 'body-parser'
  6. import * as Errors from './Errors.js'
  7. import * as Router from './Router.js'
  8. import { handleValidationError } from '@overleaf/validation-tools'
  9. const HistoryLogger = logger.initialize('project-history').logger
  10. Metrics.event_loop.monitor(logger)
  11. Metrics.memory.monitor(logger)
  12. Metrics.leaked_sockets.monitor(logger)
  13. Metrics.open_sockets.monitor()
  14. // log updates as truncated strings
  15. function truncateFn(updates) {
  16. return JSON.parse(
  17. JSON.stringify(updates, function (key, value) {
  18. let len
  19. if (typeof value === 'string' && (len = value.length) > 80) {
  20. return (
  21. value.substr(0, 32) +
  22. `...(message of length ${len} truncated)...` +
  23. value.substr(-32)
  24. )
  25. } else {
  26. return value
  27. }
  28. })
  29. )
  30. }
  31. HistoryLogger.addSerializers({
  32. rawUpdate: truncateFn,
  33. rawUpdates: truncateFn,
  34. newUpdates: truncateFn,
  35. lastUpdate: truncateFn,
  36. })
  37. export const app = express()
  38. app.use(bodyParser.json())
  39. app.use(bodyParser.urlencoded({ extended: true }))
  40. app.use(Metrics.http.monitor(logger))
  41. Router.initialize(app)
  42. Metrics.injectMetricsRoute(app)
  43. app.use(handleValidationError)
  44. app.use(function (error, req, res, next) {
  45. if (error instanceof Errors.NotFoundError) {
  46. res.sendStatus(404)
  47. } else if (error instanceof Errors.BadRequestError) {
  48. res.sendStatus(400)
  49. } else if (error instanceof Errors.InconsistentChunkError) {
  50. res.sendStatus(422)
  51. } else if (error instanceof Errors.TooManyRequestsError) {
  52. res.status(429).set('Retry-After', 300).end()
  53. } else if (
  54. error instanceof OError &&
  55. error.message === 'Timeout' &&
  56. error.info?.key
  57. ) {
  58. logger.warn({ error, req }, error.message)
  59. res.status(423).json({ message: 'redis lock is taken' })
  60. } else {
  61. logger.error({ err: error, req }, error.message)
  62. res.status(500).json({ message: 'an internal error occurred' })
  63. }
  64. })