Невозможно установить заголовки после отправки клиенту и отклонение необработанного обещания - PullRequest
1 голос
/ 13 июля 2020

Этот блок кода всегда выдает ошибку -

UnhandledPromiseRejectionWarning: Ошибка [ERR_HTTP_HEADERS_SENT]: невозможно установить заголовки после их отправки клиенту.

UnhandledPromiseRejectionWarning: необработанное отклонение обещания. Эта ошибка возникла либо из-за выброса внутри функции asyn c без блока catch, либо из-за отклонения обещания, которое не было обработано с помощью .catch (). Чтобы завершить процесс узла при отклонении необработанного обещания, используйте флаг CLI --unhandled-rejections=strict (см. https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode)

module.exports = (app, spotifyAPI) => {

    app.get('/api/search', requireLogin, async (req, res) => {

        const URI_BASE = keys.ComputerVisionEndpoint + 'vision/v3.0/analyze';
        const imageUrl = "https://upload.wikimedia.org/wikipedia/commons/3/3c/Shaki_waterfall.jpg"; // will be sent as req body
        var results;

        // making API call to microsoft cognitive services API 
        try {
            results = await axios({
                method: 'post',
                url: URI_BASE,
                headers: {
                    'Content-Type': 'application/json',
                    'Ocp-Apim-Subscription-Key' : keys.ComputerVision
                }, 
                params: {
                    'visualFeatures': 'Tags',
                    'details': '',
                    'language': 'en'
                },
                data: {
                "url": imageUrl,
                }
            });
        } catch (err) {
            res.status(400).send(err);
        }

        // remove the common ones - indoor, outdoor, ground, wall, person, woman, man, ceiling, floor
        const to_filter = results['data']['tags'];
        _.remove(to_filter, (item) => {
            return (item.name === 'indoor' || item.name === 'outdoor' || item.name === 'ground' || item.name === 'wall'
                || item.name === 'person' || item.name === 'woman' || item.name === 'man' || item.name === 'ceiling'
                || item.name === 'floor'
            );
        });

        // creating playlist and getting the playlist ID
        var playlist_id;
        try {
            playlist_id = create_playlist(req, res, spotifyAPI);
        } catch(err) {
            if (err['statusCode'] === 401) {
                req.logout();
                return res.redirect('/');
            }
            else {
                return res.status(400).send(err);
            }
        }

        // searching for relevant songs and adding them to the playlist
        try {
            search_and_add(req, res, spotifyAPI, to_filter, playlist_id);
        } catch (err) {
            if (err['statusCode'] === 401) {
                req.logout();
                res.redirect('/');
            }
            else {
                res.status(400).send(err);
            }
        }

    });
}

create_playlist = async (req, res, spotifyAPI) => {
    try {
        const playlist = await spotifyAPI.createPlaylist(req.user.id, 'TuneIn Playlist', { 'public' : false });
        const playlist_id = playlist['body']['id'];
        return playlist_id;
    } catch (err) {
        throw err;
    }
}

search_and_add = async (req, res, spotifyAPI, to_filter, playlist_id) => {
    _.map(to_filter, async (tag) => {
        try {
            const song_details = await spotifyAPI.searchTracks(tag.name, { limit: 1 });
            const song_uri = song_details.body['tracks']['items'][0]['uri'];
            console.log(song_uri);
        } catch (err) {
            throw err;
        }
    });
    // figure out where to re direct user 
}

Может ли кто-нибудь помочь мне?

1 Ответ

0 голосов
/ 13 июля 2020

Вы не проверяете возвращаемое значение create_playlist.

Представьте, что в create_playlist обнаружена ошибка, и err ['statusCode']! == 401, тогда вы go получите res. status (400) .send (err).

Затем вы go на search_and_add, потому что вы только что отправили ответ, но не указали своему коду для отмены (используя try catch в вашем "основном" "функция). Теперь, если у вас есть ошибка, и ее код отличается от 401, вы отправите ответ снова.

Отправка дважды ответа для одного вызова приводит к следующему сообщению:

UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

Будьте осторожны со своими ответами и прерывайте весь вызов всякий раз, когда вы используете res.status (4xx) .send (err), потому что после этого вы не сможете отправить успешный ответ клиенту.

...