Black Lives Matter. Support the Equal Justice Initiative.

Bu dok├╝man ingilizce dok├╝mana g├Âre eski olabilir. Son g├╝ncellemeler i├žin l├╝tfen ─░ngilizce Dok├╝man─▒. ziyaret edin

Ôťľ

Hata ─░┼čleme

Error Handling, senkron ve asenkron olarak meydana gelen hatalar─▒n Express taraf─▒ndan nas─▒l yakaland─▒─č─▒na ve i┼člendi─čine de─činir. Express varsay─▒lan olarak bir hata i┼čleyiciyle gelir, bu nedenle hata i┼člemeye ba┼člamak i├žin kendinizin yazman─▒za gerek yoktur.

Hatalar─▒ Yakalamak

Express taraf─▒ndan, rota i┼čleyicileri ve ara yaz─▒l─▒mlar─▒ ko┼čarken olu┼čan hatalar─▒n yakalanmas─▒n─▒n sa─članmas─▒ ├Ânemlidir. Rota i┼čleyicilerinde ve ara yaz─▒l─▒mlarda senkron kodda olu┼čan hatalar─▒ yakalamak i├žin ek bir┼čey yapmaka gerek yoktur. E─čer senkron kod bir hata f─▒rlat─▒rsa, Express onu yakalay─▒p i┼čleyecektir. ├ľrne─čin:

app.get('/', function (req, res) {
  throw new Error('BROKEN') // Express bunu kendi kendine yakalayacak
})

Rota i┼čleyicileri ve ara yaz─▒l─▒m taraf─▒ndan ├ža─čr─▒lan asenkron fonksiyonlardan d├Ânen hatalar─▒ ExpressÔÇÖin yakalayp i┼čleyece─či next() fonksiyonuna vermelisiniz. ├ľrnek olarak:

app.get('/', function (req, res, next) {
  fs.readFile('/file-does-not-exist', function (err, data) {
    if (err) {
      next(err) // Hatalar─▒ Express'e ver
    } else {
      res.send(data)
    }
  })
})

Express 5 ile ba┼člayarak, Promise d├Ând├╝ren rota i┼čleyicileri ve ara yaz─▒l─▒mlar ret verdiklerinde (reject) veya hata f─▒rlatt─▒klar─▒nda otomatik olarak next(value) fonksiyonunu ├ža─č─▒racaklar. ├ľrne─čin:

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

getUserById bir hata f─▒rlatt─▒─č─▒nda veya ret verdi─činde, next fonksiyonu ya f─▒rlat─▒lan hatayla ya da ret verilen de─čer ile ├ža─čr─▒lacakt─▒r. E─čer herhangi bir ret de─čeri verilmediyse, next fonksiyonu Express y├Ânlendiricisi taraf─▒ndan sa─članan varsay─▒lan Error objesiyle ├ža─čr─▒lacak.

E─čer next() fonksiyonuna herhangi bir┼čey verdi─činizde ('route' karakter dizisi hari├ž), Express ┼čimdiki iste─či bir hata olarak say─▒p hata i┼člemeyen y├Ânlendirici ve ara yaz─▒l─▒m fonksiyonlar─▒n─▒ es ge├žecektir.

E─čer bir dizideki geri ├ža─č─▒rma fonksiyonu veri sa─člam─▒yorsa, sadece hatalar─▒ veriyorsa, kodu bu ┼čekilde basitle┼čtirebilirsiniz:

app.get('/', [
  function (req, res, next) {
    fs.writeFile('/eri┼čilemez-yol', 'data', next)
  },
  function (req, res) {
    res.send('OK')
  }
])

Yukar─▒daki ├Ârnekte next, hata veya hatas─▒z olarak ├ža─čr─▒lan fs.writeFile i├žin geri ├ža─č─▒rma fonksiyonu olarak verlidi. E─čer hata yok ise ikinci i┼čleyici ├žal─▒┼čacak, aksi takdirde Express hatay─▒ yakalay─▒p i┼čler.

Rota i┼čleyicileri ve ara yaz─▒l─▒mlar taraf─▒ndan ├ža─čr─▒lan asenkron kodda olu┼čan hatalar─▒ yakalay─▒p i┼člemesi i├žin ExpressÔÇÖe ge├žmelisiniz. ├ľrnek olarak:

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

Yukar─▒daki ├Ârnek asenkron kodda hatalar─▒ yakalamak i├žin bir try...catch bloku kullan─▒yor. E─čer try...catch bloku olmaz ise, i┼čleyici senkron kodun bir par├žas─▒ olmad─▒─č─▒ i├žin Express hatay─▒ yakalamayacak.

try..catch blokunun y├╝k├╝nden ka├ž─▒nmak i├žin promise veya promise d├Ând├╝ren fonksiyonlar kullan─▒n. ├ľrnek olarak:

app.get('/', function (req, res, next) {
  Promise.resolve().then(function () {
    throw new Error('BROKEN')
  }).catch(next) // Hatalar Express'e ge├žer
})

PromiseÔÇÖlar otomatik olarak senkron hatalar─▒n─▒ ve ret edilen promiseÔÇÖlar─▒ yakalad─▒─č─▒ndan, sonuncu yakalama i┼čleyicisi olarak next fonksiyonunu verebilirsiniz ve Express hatalar─▒ yakalar, ├ž├╝nk├╝ yakalama i┼čleyicisine birinci arg├╝man olarak hata verimi┼čtir.

Senkron hata yakalamaya g├╝venmek i├žin asenkron kodu basite indirgeyerek bir i┼čleyiciler zincirini de kullanabilirsiniz. ├ľrnek olarak:

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

Yukar─▒daki ├Ârnek readFile ├ža─čr─▒s─▒ndan birka├ž basit ifadeye sahip. readFile bir hata al─▒rsa, bu hatay─▒ ExpressÔÇÖe verir, aksi takdirde h─▒zl─▒ bir ┼čekilde zincirdeki bir sonraki i┼čleyicide asenkron hata i┼čleme d├╝nyas─▒na d├Ânersiniz. Ve, yukar─▒daki ├Ârnek veriyi i┼člemeyi g├Âsterir. Bu i┼člem hata verirse, onu senkron hata i┼čleyicisi yakalayacak. E─čer bu i┼člemleri readFile geri ├ža─č─▒rma fonksiyonunun i├žinde yapt─▒ysan─▒z uygulama kapanabilir ve Express hata i┼čleyicileri ├žal─▒┼čmaz.

Hangi y├Ântemi kullan─▒rsan─▒z kullan─▒n, Express hata i┼čleyicilerinin ├ža─čr─▒lmas─▒n─▒ ve uygulaman─▒n hayatta kalmas─▒n─▒ istiyorsan─▒z, ExpressÔÇÖin hatay─▒ ald─▒─č─▒ndan emin olmal─▒s─▒n─▒z.

Varsay─▒lan hata i┼čleyicisi

Express, uygulamada olu┼čabilecek herhangi bir hatayla ilgilenecek g├Âm├╝l├╝ bir hata i┼čleyicisiyle gelir. Bu varsay─▒la hata i┼čleyici ara yaz─▒l─▒m fonksiyonu, ara yazl─▒m fonksiyon y─▒─č─▒n─▒n─▒n en sonuna eklenir.

next() fonksiyonuna bir hata verip ├Âzel bir hata i┼čleyicisinde i┼člemezseniz, bu hata g├Âm├╝l├╝ hata i┼čleyicisi taraf─▒ndan i┼členir; hata istemcide stack-trace ile beraber yazd─▒r─▒l─▒r. Stack-trace ├╝retim (production) ortam─▒nda dahil de─čildir.

Uygulamay─▒ ├╝retim modunda ko┼čmak i├žin NODE_ENV ortam de─či┼čkeninin de─čerini production olarak ayarlay─▒n.

Bir hata yazd─▒r─▒ld─▒─č─▒nda, a┼ča─č─▒daki bilgiler yan─▒ta eklenir:

next() fonksiyonunu yan─▒t─▒ yazmaya ba┼člad─▒ktan sonra bir hata ile ├ža─č─▒r─▒rsan─▒z (├Ârne─čin, istemciye yan─▒t─▒ aktarma esnas─▒nda bir hata ile kar┼č─▒la┼č─▒rsan─▒z) varsay─▒lan Express hata i┼čleyicisi ba─člant─▒y─▒ kapat─▒p iste─či ba┼čar─▒s─▒z k─▒lar.

├ľzel bir hata i┼čleyicisi ekledi─činiz zaman ba┼čl─▒klar (header) halihaz─▒rda istemciye g├Ânderilmi┼č ise varsay─▒lan Express hata i┼čleyicisine yetki vermelisiniz:

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

Kodunuzda next() fonksiyonunu bir hata ile birden fazla kez ├ža─č─▒rd─▒─č─▒n─▒zda varsay─▒lan hata i┼čleyicisi tetiklenebilir, ├Âzel hata i┼čleyici ara yaz─▒l─▒m─▒ yerinde olsa bile.

Hata i┼čleyicileri yazmak

Hata i┼čleyici ara yaz─▒l─▒m fonksiyonlar─▒n─▒ di─čer ara yaz─▒l─▒m fonksiyonlar─▒ gibi tan─▒mlay─▒n─▒z, bundan farkl─▒ olarak hata i┼čleyici fonksiyonlar ├╝├ž yerine d├Ârt arg├╝mana sahipler: (err, req, res, next). ├ľrne─čin:

app.use(function (err, req, res, next) {
  console.error(err.stack)
  res.status(500).send('Bir┼čeyler bozuldu')
})

Hata i┼čleyici ara yaz─▒l─▒mlar─▒ di─čer app.use() ve rotalar─▒n ├ža─čr─▒lar─▒ndan sonra, en son tan─▒mlan─▒r; ├Ârnek olarak:

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

app.use(bodyParser.urlencoded({
  extended: true
}))
app.use(bodyParser.json())
app.use(methodOverride())
app.use(function (err, req, res, next) {
  // i┼č mant─▒─č─▒
})

Ara yaz─▒l─▒mdaki yan─▒tlar HTML hata sayfas─▒, basit bir mesaj veya bir JSON karakter dizisi gibi herhangi bir bi├žimde olabilir.

Organizasyonel (ve daha ├╝st-d├╝zey ├žat─▒) ama├žlar i├žin, normal ara yaz─▒l─▒m fonksiyonlar─▒ gibi, birden fazla hata-i┼čleyici ara yaz─▒l─▒m fonksiyonu tan─▒mlayabilirsiniz. ├ľrnek olarak, XHR kullan─▒lan ve XHR kullan─▒lmayan istekler i├žin bir hata i┼čleyici tan─▒mlamak gibi:

var bodyParser = require('body-parser')
var 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)

Bu ├Ârnekte, jenerik logErrors, stderrÔÇśa istek ve hata bilgileri yazabilir, ├Ârne─čin:

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

Ayr─▒ca bu ├Ârnekte, clientErrorHandlera┼ča─č─▒daki gibi tan─▒mlan─▒r; bu durumda, hata a├ž─▒k├ža bir sonrakine aktar─▒l─▒r.

Bir hata i┼čleme fonksiyonunda ÔÇťnextÔÇŁ ├ža─čr─▒lmad─▒─č─▒nda, yan─▒t─▒n yaz─▒lmas─▒ndan (ve sonland─▒r─▒lmas─▒ndan) siz sorumlusunuz. Aksi takdirde o istekler ÔÇťhavadaÔÇŁ kal─▒r ve ├ž├Âp toplama (garbage collection) i├žin ge├žerli olmayacakt─▒r.

function clientErrorHandler (err, req, res, next) {
  if (req.xhr) {
    res.status(500).send({ error: 'Bir┼čeyler ters gitti' })
  } else {
    next(err)
  }
}

ÔÇťHepsini-yakalaÔÇŁ errorHandler fonksiyonunu a┼ča─č─▒daki gibi tan─▒mlay─▒n:

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

Birden fazla geri ├ža─č─▒rma fonksiyonu olan bir rota i┼čleyiciniz var ise bir sonraki rota i┼čleyicisine ge├žmek i├žin route parametresini kullanabilirsiniz. ├ľrnek:

app.get('/a_route_behind_paywall',
  function checkIfPaidSubscriber (req, res, next) {
    if (!req.user.hasPaid) {
      // bu iste─či i┼člemeye devam et
      next('route')
    } else {
      next()
    }
  }, function getPaidContent (req, res, next) {
    PaidContent.find(function (err, doc) {
      if (err) return next(err)
      res.json(doc)
    })
  })

Bu ├Ârnekte, getPaidContent i┼čleyicisi es ge├žilecek ama app uygulamas─▒ /a_route_behind_paywall yolu i├žin geriye kalan herhangi bir i┼čleyici ├žal─▒┼čmaya devam edecek.

next() ve next(err) fonksiyonlar─▒na yap─▒lacak ├ža─čr─▒lar ┼čimdiki i┼čleyicinin tamamland─▒─č─▒n─▒ ve hangi durumda tamamland─▒klar─▒n─▒ belirtir. next(err) ├ža─čr─▒s─▒, yukar─▒da g├Âsterildi─či gibi hata i┼člemek i├žin kurulanlar hari├ž, zincirde geriye kalan b├╝t├╝n i┼čleyicileri es ge├žer.