Ошибка не может быть поймана с Express.js и gridfs-stream

Это простой сервер загрузки изображений (картинок), Express.js получает запрос, получает изображение из MongoDB GridFS и отвечает файлом.

Это нормально, когда запрос действителен (когда запрошенный файл существует).

Проблема в том, что я не могу поймать MongoError когда запрос не удался (т.е. запрошенное изображение не существует).

import Grid from 'gridfs-stream'
const root = 'fs_images'

// This func returns the file stream
export function getReadStream (id) {
    const gfs = Grid(mongoose.connection.db, mongoose.mongo)
    const options = {
        _id: id,
        mode: 'r',
        root: root
    }
    const readStream = gfs.createReadStream(options)
    readStream.on('error', function (err) {
        // throw here
        // it performs the same without this on-error hook;
        // if comment the `throw err`, nothing will happens
        // but I want the caller knows the error
        throw err
    })
    return readStream
}

А это роутер

router.get('/:fileId', function (req, res, next) {
    const fileId = req.params.fileId
    try {
        const imgReadStream = image.getReadStream(fileId)
        imgReadStream.pipe(res)
    } catch (err) {
        // nothing catched here
        // instead, the process just crashed
        console.log(err)
    }
}

И я просто не могу поймать ошибку. Когда я пытаюсь запросить что-то, что не существует, MongoError отображается в консоли, и приложение вылетает с errno является 1,

Глава консольного вывода:

/.../node_modules/mongodb/lib/utils.js:123
process.nextTick(function() { throw err; });
                              ^
MongoError: file with id 123456123456123456123456 not opened for writing
at Function.MongoError.create (/.../node_modules/mongodb-core/lib/error.js:31:11)

Это может быть немного по-другому. Если где-то еще кидает Error это поймает мой обработчик ошибок (app.use(function(err, req, res, next){ /* ... */})) или, по крайней мере, обработчиком по умолчанию из Express.jsи возвращает 500, без сбоев процесса.

Короче говоря, я хочу, чтобы приложение знало и ловило это MongoError так что я могу справиться с этим вручную (т.е. вернуть 404 ответ).

1 ответ

Решение

try/catch не будет работать, потому что ошибка происходит в другом тике (асинхронно). Возможно, вы могли бы вместо этого прослушать ошибку в роутере?

const imgReadStream = image.getReadStream(fileId)

imgReadStream.on('error', function(err) {
    // Handle error
});

imgReadStream.pipe(res)
Другие вопросы по тегам