Проблемы с областью действия в try / catch при использовании async / await - PullRequest
1 голос
/ 24 октября 2019

Моя проблема в том, что (казалось бы) вещи выходят за рамки или загрязняются, когда я вхожу в свой блок catch в функции ниже:

export const getOne = model => async (req, res, next) => {
  let id = req.params.id
  let userId = req.user
  try {
    let item = await model.findOne({ _id: id, createdBy: userId }).exec()
    if (!item) {
      throw new Error('Item not found!')
    } else {
      res.status(200).json({ data: item }) // works perfectly
    }
  } catch (e) {
    res.status(400).json({ error: e }) // TypeError: res.status(...).json is not a function
    // also TypeError: next is not a function
    // next(e)
  }
}

Интересно, что с использованием res.status(...).end() в блоке catch работает просто отлично, но меня беспокоит, что я не могу отправить какие-либо подробности обратно с ответом. В соответствии с экспресс-документацией для res.send() и res.json я должен быть в состоянии соединиться с .status(), что также довольно интересно, прекрасно работает в try утверждение выше, если все прошло успешно - res.status(200).json(...) работает отлично.

Кроме того, я попытался абстрагировать обработку ошибок до промежуточного программного обеспечения, , как предлагается в документации Express , и через замыкания, я долженпо-прежнему есть доступ к next в операторе catch, верно? Почему это возвращается не как функция?

  1. Почему res.status(...).json(...) работает в моем try, а не catch блоке?
  2. Почему next больше не работаетфункция в блоке catch?

Заранее спасибо!

Редактировать

В модульных тестах происходит сбой, следующий код выдает ошибки, описанные выше:

describe('getOne', async () => {
  // this test passes
  test('finds by authenticated user and id', async () => {
    expect.assertions(2)

    const user = mongoose.Types.ObjectId()
    const list = await List.create({ name: 'list', createdBy: user })

    const req = {
      params: {
        id: list._id
      },
      user: {
        _id: user
      }
    }

    const res = {
      status(status) {
        expect(status).toBe(200)
        return this
      },
      json(result) {
        expect(result.data._id.toString()).toBe(list._id.toString())
      }
    }

    await getOne(List)(req, res)
  })
  // this test fails
  test('400 if no doc was found', async () => {
    expect.assertions(2)

    const user = mongoose.Types.ObjectId()

    const req = {
      params: {
        id: mongoose.Types.ObjectId()
      },
      user: {
        _id: user
      }
    }

    const res = {
      status(status) {
        expect(status).toBe(400)
        return this
      },
      end() {
        expect(true).toBe(true)
      }
    }

    await getOne(List)(req, res)
  })
})

1 Ответ

1 голос
/ 24 октября 2019

Почему res.status (...). Json (...) работает в моем блоке try, но не catch?

Похоже, вы передаете не-Экспресс-объект, который имеет только методы status & end при запуске с использованием модульного тестирования. Вот почему он не может найти json метод

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...