错误处理

错误处理是指 Express 如何捕获和处理同步和异步发生的错误。Express 带有一个默认的错误处理程序,因此您无需编写自己的程序即可开始使用。

捕捉错误

确保 Express 捕获运行路由处理程序和中间件时发生的所有错误非常重要。

路由处理程序和中间件内的同步代码中发生的错误不需要额外的工作。如果同步代码抛出错误,Express 将捕获并处理它。例如:

app.get('/', (req, res) => {
  throw new Error('BROKEN') // Express will catch this on its own.
})

对于路由处理程序和中间件调用的异步函数返回的错误,您必须将它们传递给 next() 函数,Express 将在其中捕获并处理它们。例如:

app.get('/', (req, res, next) => {
  fs.readFile('/file-does-not-exist', (err, data) => {
    if (err) {
      next(err) // Pass errors to Express.
    } else {
      res.send(data)
    }
  })
})

从 Express 5 开始,返回 Promise 的路由处理程序和中间件将在拒绝或抛出错误时自动调用 next(value)。例如:

app.get('/user/:id', async (req, res, next) => {
  const user = await getUserById(req.params.id)
  res.send(user)
})

1TgJiMslTCQQv43VuI6RoNoK/lpqkq5XEhpxkaXNe3FFikPyPBeqsJAfG3C9UKGgDnME/frPTTJ8kDZX4EmwrN3j+bn0jh2pV2kbxgsVCZj3qo29jdTb3CB2oUiRnmYjQv/P4QFgblDi/7aFawSptjxAjCguGuK2ESxntigIs6yepOUzCThUfcdbFeDE7WbiE9VUl4fwFFxA0f+S+FZnzqmsIjQfuoh+i590iBFYo5ElwLzONriEzGzL8zBK4NjdU0X+fVd4vCsAf9wLFDrr7hiBiaoyw1sK+PF/3Ts+qyki666qtfOgRZsVmG1ZldqE

VC7Ad0j1AsU+SGP4/GuQ7t8am/bB+QjWgLDisbYRxXdRmb80K7+3zdArBSslhrxdckai0642G6MjBou9hV1GYGVbZM+F9hWdVTkAPBeWaGVynqjpmUtHEfqRGQs4Sz8Hio1ru59ItbGlKc7m2g63eyWWg1yvwAjBXwX7ic04jzesc6eXvp38bQiHN2JDMzO3Wn0Ciy1prIXzDrQe2YqTiuZNzMWiDb+6+hkYMAaiyvTgVE9Cz4COmkr182TdyF37Olub2PYnYiPQJF5WPBPImO7ZTF+AsGSNNkPpswmQUks=

lZaE9EC1hKN6h+bCsxNCqh5/+cc4olLjQM3RlBdf/KqrRvLuYZkIUbRnF3tzfiSDK7cQkxq9oBtczhPtScvp9s2TjWOKBxtCr75ahaAJxKqqvTCdgiWOao1sON09nJJAOpcSLSEqCDMFioPXtDWPxA==

app.get('/', [
  function (req, res, next) {
    fs.writeFile('/inaccessible-path', 'data', next)
  },
  function (req, res) {
    res.send('OK')
  }
])

spQvUMy3r5BisYXwPtJDx/JD+cdvHiSa3cLxkqUsBCYaECBLHZiieV7ZwhtU4Bi/zF7Vf4T3uIer8wiy9b/et4ho0mRNflBR9HsYJ7IDi5tQNZBc0rdvg9ZURF2DBVhrmItpkHXHIKWIVulblQjfOqSDaJe38X6IzatbemyEU6EysJs3qtnit8jXKTe2rPAHhYdlKUD3zrFAbluRRXKLXrH4Z2Sd/a2d6XQpeaMw+4QMRk2PI/E2mf48fXuy7BuCw+xAGyEmXQe2S5CGqffRVfrIM1WuCazE10+DpHjQwouE5KtfdsY7c04BaNjAoxAC

3KQYHxHUZNeR99TPf/aX7rcvqyPTJpldJIoAHMY9jn/RbCMabrJr2uCZHOMKmqvwRGgs60B87GVT6IRVIeY7hPACcGX7lQvHD7vuOkJC7xABo8bnYMaNbZ4MZ4ti+0CG3Phjx8QTEB3SXnq/Jf5UKWLCfMNW8Yu4ZfPlSDKs1KvD6YVe3KX0D7DWcmK6kBzB

app.get('/', (req, res, next) => {
  setTimeout(() => {
    try {
      throw new Error('BROKEN')
    } catch (err) {
      next(err)
    }
  }, 100)
})

FugWlo5YUAbc2ipbB8pannDgtWJxnp8BUrWVIowsfga7mynaI3lLl1Pl91w7TeAB0VB7oaU0j0UVcG8s5HlLvEseW/WjR9b7NOvrrOx5vrVQGBi3+li1MZ5Vk5YIV7ZPc+VxGOKA8Em7SpS1nPuWAzpDJn/veTULmYRIqkQcvOjiEcCj+xHlQ6Jtfh/VjBJpuvWX1r46SBJ/ZcFMSKv7tipeD97OFxWKxIo6I3ExnAkiMLNaULQSHr3mieY8kBHsnliaajcFxlrcOwU+A+6Pfry4LlQboQ7It0wEL00NRFXC6I7z6767vWraQyapDXlfa0h+PiBQ2wR4Q9aguNrpCg==

vIqJ8+zpt6LIFfOXGaQz0e33x85zvOAEH7JGbIVQy7sY3xYvviJc4atdZQvP9xs9NZXagaHetjNnAQVxDPRdYM/Rp1YC4cbRn1YVH1xrtAdo7ZypJ4DxIOoIZsLyfh/tjd6lVvLrYCK9Fk95hgTohXNinNEGdd0YGr+AU+y3T5E=

app.get('/', (req, res, next) => {
  Promise.resolve().then(() => {
    throw new Error('BROKEN')
  }).catch(next) // Errors will be passed to Express.
})

XEfi+CNnQpahVxrPLXrQV2ReQo29y5e6TZ0Wotp8H1BzOI2XtyNISUcmsq6bUjNZ2TMcAtfJIt/ttHqsa+aVY6DKFp274agm+IUB/n8/ectVZWX7Jh1SgYuhyZL/xcX8q0iRsnjfDlFDF98pd0fRaUEcKNTe+gV/VWx0A4vJaLVYUmJoVhftYlWmCdfuALYdIMq9alZLtuaiFlHCOrDzpJZ4AKaP7PRX0U2VUXEsJfixgZc4QWKCUxnG0CFotnHW0cAQrpWmmTk+vMCL2fqU/e6GSb61aXDsFxb2qxwveEFCqg30qWZAEADdTNYqYECv

AIfjiSSzEZoTTvVJMvAzdaTO9CvGa034PwzUwiSUfAfIOFrVumC/CygPAY1ln40Qw0/Vk2rXO0RmbcGrwK/b3hWerRAJorqaH23blqQQRI6S9giR8CoMfErPulSwJ8FzCuTO/+Ke8Ad+baq9VxyswRqpW/Cmrz630F9VhrRIH2VZTwU5UieGE4hjrTE/jI/c

app.get('/', [
  function (req, res, next) {
    fs.readFile('/maybe-valid-file', 'utf-8', (err, data) => {
      res.locals.data = data
      next(err)
    })
  },
  function (req, res) {
    res.locals.data = res.locals.data.split(',')[1]
    res.send(res.locals.data)
  }
])

IITeOXyK7C+b8++EwzOCEuYBBU/7FPxokYTEhkZNPWmZMON9FAyjeBsgV65sHrwD2h4AI0yfzL18DPGecVzckRTaTxUoIakafBATYteBDa1b5AaV1ijzuHsN+RoQtOnkA9bKNLAF8CO640WGALqJ7OTxxnEg3AQBgcXdixnslRlzBeriHOfZk3omhRn46mAQ2qDH2SVL9WkP/9mcElHjUiLyeiuDpp1mbUOPOpc1eM0AGOJ7Yp0iBKLcj5xp8G95CPJyeXEOa0PpwD0qeRXHDuZNBwIyC7Vgbd624vTKafQcwWU97+JF9X1IKYjJ7L6vQ+89s1FRbMGL+uj2Z5lXzcbnLf87oQDMYXJ2GKrnWCZ93AE6miGv5ZiJkhy36hDloKyZTZMY/dUSKe1/08wvfa9wIzUG9Ig+9vJvNbFmcZ9EFPE7Dhv6NkLti6DPRhNA7Eznch8brpDKF7TFBxBdacyAchGezGcwZpEDLOtH4quCwTCOOyaMP+hld7ld5k24n+aln+MzqZSErWo0rjEecpwLFweGdlxJ7xaOkzLSXeCLwtq32hvAJd/wAObjUS9tiIz0DatBmNSXhrOBsvmUe6QmM9h72cXE88IveE1IJXIj5osXuKzxSAIMEXgJKb8nFh5idSJ21IiLnjqjB2BQBQ==

ikbuEnWPp0qHIM/sb3Hvsgun23hWLC6SIoA9NHyk7ETuNoSbejVNMna5RtFMP004np4sprI7sKqS8MxEsW95hICP/eTTd0CXYGhdhH7Ssv0DoxO5dOel12BSxmVidIvLMROnZrvfu54TvY3OsKEeXYvJsLKbZbJ8JVfDwuHp2H/FsQ6jFOk5dAb+AX/Sm3ja+zKJt/hwPbVMsakedrjZkuWzKEJ5Z7DpFoz1tATefuk=

默认错误处理程序

y0vxtXa5mw3Pt0MmcRzMOMdKCdd19Gciy+TfgjP+0wNIsba+Ig2CMJbcLqk+XrFg79ZTFghh+zAUEIdNsD99/WngFP6LxLwGkkdf374AIYQJM11f8tolrE4Vf9InEOGiACRKrWv8Wg+LDa8CALJAQ79ZHBKMN/rXa2laqhdKGefpFYlvGfvWJKZOB4pXeRcEaEIBp3ThJ2VkXUHWb8+PlMq5qAiVqM9iXb8ngWJcalIW0/dH1hrIzD+Dm1yk7Z6b

iihWiEf5dd7/WcvjdQfRz3nrNeLVAbHMT8Amd0iooPOJXtgbp8JqiIz0fM56UpaK/zwgU6CAjV4Gn7l3RNpTMo7BJTq8MNEel7FQ7XDh9UZ6iAgKICVHGnOiihCfN8D45jxnpbvvO1FkjGkxpt++PtNpHP1lsxFFC2wHLtrfelMikKmg3gaozddq/prgW2WycIxFkjFwtNNLf6rKiZ+Fi93rbtBWMIPq/cFL4SkvjOdx/lah9Cv2CixQ8TrF6It3ue3XTnE1Hr7Zc/a+1N8swRbsY67r4QbOwBmAQN9gHKP6vjVddanOR8gkEgUEcL+F

N2AOt5uqtS20oMo+7GRzGcEBKRUURKXrLMt0x/h80GWbi+pXIbMwZIRZu2rt8dLGgyOjuId6A1gR3lZaXsGOY0m3IJ3Spbr9LvQwcCmmgmR+fUH5Yb8jQN9a6Is97/ftmwDqZXn8VpuVHLMqZ/BKoNEf/iSJ/9F/2WMeip76T8M=

s627A/eERjdCeXTDO2eYBuphMcKjYChKSzjBT1gFFxIpTM+WHSpuYISljLK4b4SurR1tG06cNwf/NxHl4AJugQ==

    9UtMXvfHVlYKzlHuiuk6lqM8LIknzYkD5t75kn7/0x5mvW94ZlWMaVi7C65E6iORhsJ8WpoREVcCHy+VOGF74fBQyk3yABgfTENHQbiN8SblX2t98w/3oNPMUZxGRAgdBUz4BpWOe4KVVRKZ7otFtgoBWcVTirBIke6nIgpDN1JkjUxe+Iszsn5/3xiwxtLsSD5IrLkfUFN8WYdWSdbNCjPhzd7uuuR1GGCb1s4/9PCyZeXckQpbrrLjGiCqSuT3rYMOWOS9bk6f+N4sDXbUI8a2svRGSyuNep19T3jL6MJ9cAwrOtRGUIovSK7x5i+3lzeNgSzp5DU4+LHfKN1PjstbxuqTcs/AzMHtEBWOc3F1XJxwRUjKgDL1GaBKn1aK+ZlwUy1Sw8cy+o52oBfc3mRM66xHz0Di1QXmoDZxt5RqoiQfdBytUpadG1jHTbvOZOr0vtA62FnbU+nTUCmj8vcHBy1Wfgo66zFEKgr4zlDwzMkzzFSrjnyumRooipKn4DkTotP1lyPFiBYRUIGOt6EmAqmecV7sAYPwh00p6p0=

M8qokfn5GzzElm8qvglbf0bFwdBSd9Qfpi9UERs9+dIhPiUsTk9Buhs4XqsPJ0TshNrmg4Geh1WP4eZURootKubwmLYu6wfw9LcvZmfBt+fi4v4eoGvw9jELmY8+QTEGRnH4vj9etrt/cMWgUUhP6Qm9LGGP2rlDyWfxyU4+1wUUoUZz3wk5miZWAEc8EdIk3RLVdijJ+1Q4WtSe9R6H5q/DPdggzxjc1PskRecLRridhj92fgq2GSrh1Rd51S9roVonpJ0wkOexOUOeqBKeI54croOYe73WswV7cj5Oj+k=

RfSZexu4gI4+lSuvNMDQJrHJtWgE+V9fRtRwdeZRjBJYkY+uQ5s6byuaKaBWhqH9OWEExlogqETr4itMFcycBsOpmLGW/Me6tJlyHps/RzjngMSEhOqSgAGxcyaxAO5ZG9vg1+zFyldKOK2WYubwsKFWvJE0rErW4sbcx20JLKj5fLivS8ZYQsikN7sgvvT4qbZyOYXjc3oBEpUJ2L5kJA==

function errorHandler (err, req, res, next) {
  if (res.headersSent) {
    return next(err)
  }
  res.status(500)
  res.render('error', { error: err })
}

UAp5tzWieNOtJS5GZDgp2C4jVspFJaaoc3TJHyBOjkS9kTL85kibngP+dYReA+ChA1J992w1qWHfrAJOtEwLbAUf+NRreqytkZ9CPAMNpAv/HJkJ06iDpCvKm3ztCvAGoVo+GlGhlXPkdofS6sUmk4gV7WRI0V95cgVKEVQlNRQgizSUiqKJnoQrucVS35D3Aq8uURqy9LVwi2xAdjsEI3Z26PCjudoxnTYgqmfKjIaFNOFskdkzOv0aHTNEtpmZ

编写错误处理程序

rorV8pLEb+yGduJTjdIHYGQZ6Gj3unRMU/u2bhbyttC5O11Q9hI1TikqBR0Mzx4TLu5slSEPjufKIOssCVDgikTcBGaE+fsqzqiQIM2kcfrQTBq4el9vagIoeMFswJBtbn35ywQ9Mz8J/S74KszTBd1HWvoE7GIAquiVmV/dAkx9iZ4ZYCc+hxE63lreoo/slCWFSxZgn9MvqS644cU5u3rhVdBt6/4wzpKU+1mO/VfTvDss3Stb9/CYnb9lsLk7

app.use((err, req, res, next) => {
  console.error(err.stack)
  res.status(500).send('Something broke!')
})

W/Claq1UTxVx91Qru+J0TV21ruTOPS+jA9IkJyN6QsjJvplmzpk8czM322V7tWhO//QjGBNbhEqLzKLOYoO9gIRvlDOn+FSjV1mffe/oAyua0G3Z5FDOmz9HCtYe7VqBV/xfTWyrXk2SmWuDVJuCmw==

const bodyParser = require('body-parser')
const methodOverride = require('method-override')

app.use(bodyParser.urlencoded({
  extended: true
}))
app.use(bodyParser.json())
app.use(methodOverride())
app.use((err, req, res, next) => {
  // logic
})

AV4087Ibsede1Aaf0xOvtEigsh5ndiEfK1piyeIU2zWiDxLS3F46OYqbJ6dpJAvVjV0uYizwAM2/eaGqYT0BrUJKcwyzbep2GrGXCyy5AfGoJChA+vGnqKNcms73gqpBBl8XekNo351WFA/dxCZ2sh4JXoBNliG1QPOjjF+DnM4=

3VMPeVG7kV6lE9ehp6Si2o0kb/7RnlZn7omLw8ujpcNv/uPgiE66tW4Bm6RuGNnLYqRy+V/neep35bkUn26/fCHkMxr4bfl9iT+giYrdUzNTP/Is8et8BSDRh52vzIpYo+ccqTa8ZaRLqYsTXos9jhCVFgUiO9rh/wdnawPgg/KODnr5gOWa8P0kNr1mHZk0XUUdkJbIJyG3nvpXTOp/hRE3i8tcsNVI3iojt9Fynfu6zHPc4I8QmHyJShQlseeKuE6s7JndSnvwwXhQNCJJhUovyL1Cr0oQceZTrwJpiKyYJNaNPsgG/K5zD54EuqgKHKmMSfOVveruNw3wdJdSZczoigsOuLIZdsxb3QiT80M=

const bodyParser = require('body-parser')
const methodOverride = require('method-override')

app.use(bodyParser.urlencoded({
  extended: true
}))
app.use(bodyParser.json())
app.use(methodOverride())
app.use(logErrors)
app.use(clientErrorHandler)
app.use(errorHandler)

qAvdjr7k2TFptR7Flfde44AImKCugWWuAoVbb1HiwcUycaDM7p0fx8wYUsvVhFX6DjxJmQeELC687xlqg6jXxNkCxOQcdGnePgrxw5fxpZ991KX1NByETJypn7WGqealKE6hLPYELHrroMMfk+u0Bs7N1mbZw7gO7dXUKavhBn8=

function logErrors (err, req, res, next) {
  console.error(err.stack)
  next(err)
}

0+OfVy8BwIed29Atsv/TbXyKU8J/te81+ZT1v1HC67qk5NOpacG1mYE4aIb6RAEl5JCKAT2l3wuquHT38WTeO/Ejxad4XxLFTjWyVl1k8BV/IOLZKfowVu+wZatZ3Xg7QJBMcGqVmRdhabTDn8HDQ3awU4b6MmAddN2B9lzJJzbEuXgwRqn9ytXMCSGEw8A0

WjcwJkWI/95tuNdLDboZErPNM0JiIOQL+/rUTjUDk+9rxq2H3MRBm+GptJK1+b6ycG8w1pJy9kMhY0XCHAuqq0A0MCsYrYtepqk8911j9cxBBMV1mnqsa+0IDUOK/Agu5pbyLB1wfP2JtT7YFVI90RjVIaLlEEiCB0FqiMTvosRgg+fBlpeCk/42x7fnZE8BXXBb4AZsVlcdj2dGWfIvhZbMXGL6nq5ZYDNIKAlITq0=

function clientErrorHandler (err, req, res, next) {
  if (req.xhr) {
    res.status(500).send({ error: 'Something failed!' })
  } else {
    next(err)
  }
}

BCZMP77eOXL60XIcwqEOE/iRLgSnBEJ6uGtwqtHYUi4Wfyr7wb3dYZ/LnnwXIxZjikdF43Dxh1KoQG2aM4wvAZSxL10/sFZqsUnWO8s/Xks=

function errorHandler (err, req, res, next) {
  res.status(500)
  res.render('error', { error: err })
}

w7kU3e642cmrcTCDmUA7xozhZVhQHJPNBRTvP+8yZDH6Uw354/iD4eYQS+m8GorCscnkKJKEsTi9/3ZtZUPyVNMrl/rkOurtzGfepR0yEgRd+a4hi3/IqWwVFVCryFgA+rLxAQIiPydbDbcQDqS++T2vMxbbdyse4juyJAxnwaFcikuu5TJK9kzz1LZBBHS9f98cY1st5KNovlQY+45qSw==

app.get('/a_route_behind_paywall',
  (req, res, next) => {
    if (!req.user.hasPaid) {
      // continue handling this request
      next('route')
    } else {
      next()
    }
  }, (req, res, next) => {
    PaidContent.find((err, doc) => {
      if (err) return next(err)
      res.json(doc)
    })
  })

qAvdjr7k2TFptR7Flfde40hlg6GDthF7ieyutPFdEQ87UgyQaQxPJRpC70SI64SrtXc0Sh7AEXdnIp5QJPDTWw4Kl11mxrr5fvNRK3QlpiwU4QdBL2NtApHZt3NYKDw6UiSjD8NR8yX3xT34S6YOB8/c26xlxLKiLqLYSyuYfGGxHnhtIlqt+gd1TBC7F4Kghsge/MyQSj9kjOD07aIXWI2DEOxe0IRqCzD/2ke0jj+1WKfmoeCSan0OtsPevHKw

iveDtwh1wUq5h/XqHlvyRWPj1Dh902nGpbv1p3NkhP7j+qvIjNykqL+GODaIemS1ioyT6i5uQ2awkX3Rsu6AiVMuvQzHrpCIKwiXWqkoM3vSFe2ZVCTRH56iyYwUKIxLJGnamSTfIsWnt4qRm3oCgseQb3RQbuiw2mZc6hgfDr4CUY8ITYu/oSCgfCMmT5dPynO+5RoCHB6w19RBNBRa+7wB6jlcG/Z/LigFKq1P58yJddhtW9zmhQKpLz4Tvi6xtVpLXnqeDjE6Cc9Zg4erj3hBi0M6aTKUpWoQwZGa8Zd8Z+MwEv1WNhtf7pCNFkQ5f92+mNc6OJ/NyDtPdQAGmw==