RHeactorJS/server

View on GitHub
src/api/send-http-problem.js

Summary

Maintainability
A
3 hrs
Test Coverage
import Promise from 'bluebird'
import {HttpProblem} from '@rheactorjs/models'
import {
  AccessDeniedError,
  EntryNotFoundError,
  ConflictError,
  EntryAlreadyExistsError,
  ValidationFailedError,
  EntryDeletedError,
  PaymentRequiredError
} from '@rheactorjs/errors'
import {URIValue} from '@rheactorjs/value-objects'

export const HttpProblemFromException = (exception, status) => {
  if (exception instanceof HttpProblem) return exception
  const url = 'https://github.com/RHeactorJS/nucleus/wiki/HttpProblem#' +
    status +
    '?title=' + encodeURIComponent(exception.name) +
    '&detail=' + encodeURIComponent(exception.toString())
  return new HttpProblem(new URIValue(url), exception.name, status, exception.toString())
}

/**
 * @param {string} environment
 * @param res
 * @param err
 * @returns {Promise.<TResult>}
 */
export const sendHttpProblem = (environment, res, err) => {
  let status = 500
  let punish = false
  let punishTime = environment === 'production' ? 1000 : 0
  if (err.name === 'TokenExpiredError' || err.name === AccessDeniedError.name) {
    status = 403
    punish = true
  }
  if (err.name === EntryNotFoundError.name) {
    status = 404
  }
  if (err.name === ConflictError.name || err.name === EntryAlreadyExistsError.name) {
    status = 409
  }
  if (err.name === ValidationFailedError.name) {
    status = 400
  }
  if (err.name === EntryDeletedError.name) {
    status = 404
  }
  if (err.name === PaymentRequiredError.name) {
    status = 402
  }
  if (err.name === 'TypeError' && /^\[tcomb] /.test(err.message)) {
    status = 400
    err = new ValidationFailedError(err.message, {}, err)
  }
  if (status === 500) { // Unknown
    console.error(err.name)
    console.error(err.message)
    console.error(err.stack)
  }
  return Promise.delay(punish || err.punish ? punishTime : 0).then(() => {
    return res
      .status(status)
      .send(HttpProblemFromException(err, status))
  })
}