Как правильно отформатировать вложенные блоки try / catch внутри функции, которая возвращает ответ сервера - PullRequest
0 голосов
/ 13 апреля 2019

У меня есть вызываемая функция, которая должна возвращать ответ серверу. Внутри этой функции есть два await вызова функций, которые являются вложенными. Чтобы отслеживать обработку ошибок, я добавил try/catch блоков. Есть ли способ избежать наличия вложенных блоков try catch для отслеживания всех случаев, когда функция может завершиться сбоем, чтобы я мог отослать ответ сервера с ошибкой?

Вот моя функция, она запрашивает уникальный идентификатор устройства пользователя и отправляет push-уведомление каждому. Если токен становится недействительным, я удаляю его из своей базы данных:

function findUserDevices(uid: string, message) {
    collectionData(fb.firestore().collection('devices').where('userId', '==', uid)).pipe(
        filter((userDevices) => userDevices && userDevices.length > 0),
        take(1)
    ).subscribe( async (devices: any) => {
        var userDeviceTokens: string[] = devices.map((device: any) => device.token);
        if (userDeviceTokens !== undefined && userDeviceTokens.length != 0) {
            try {
                message['tokens'] = userDeviceTokens;
                const pushResponse = await admin.messsaging().sendMulticast(message);
                if (pushResponse.failureCount > 0) {
                    const failedTokens = [];
                    pushResponse.responses.forEach((resp, idx) => {
                        if (!resp.success) {
                            failedTokens.push(userDeviceTokens[idx]);
                        }
                    });
                    failedTokens.forEach( async (token) => {
                        var tokenInstanceID = token.split(':')[0];
                        try {
                            await deleteOldToken(tokenInstanceID);
                            console.log(`Token ${tokenInstanceID} deleted`)
                        } catch {
                            return res.status(500).send("err");
                        }
                    })
                    return res.status(200).send("ok");
                } else {
                    return res.status(200).send("ok");
                }
            } catch {
                return res.status(500).send("err");
            }
        } else {
            return res.status(200).send("ok");
        }
    })
}

Это кажется немного чрезмерным со всеми returns, которые я должен иметь. Где я могу улучшить?

РЕДАКТИРОВАТЬ, разбить код на три блока, чтобы предотвратить кодирование стрелки

function findUserDevices(uid: string, message) {
        collectionData(fb.firestore().collection('devices').where('userId', '==', uid)).pipe(
            filter((userDevices) => userDevices && userDevices.length > 0),
            take(1)
        ).subscribe(async (devices: any) => {
            var userDeviceTokens: string[] = devices.map((device: any) => device.token);
            if (userDeviceTokens !== undefined && userDeviceTokens.length != 0) {
                try {
                    message['tokens'] = userDeviceTokens;
                    const response = await admin.messaging().sendMulticast(message);
                    const oldTokensArray = checkOldTokens(response, userDeviceTokens);
                    if (oldTokensArray.length > 0) {
                        await deleteOldTokens(oldTokensArray);
                        return res.status(200).send("ok");
                    } else {
                        return res.status(200).send("ok");
                    }
                } catch (err) {
                    return res.status(500).send(err);
                }
            } else {
                return res.status(200).send("ok");
            }
        })
    }

function checkOldTokens(response, userDeviceTokens) {
    if (response.failureCount > 0) {
        const failedTokens = [];
        response.responses.forEach((resp, idx) => {
            if (!resp.success) {
                failedTokens.push(userDeviceTokens[idx]);
            }
        });
        return failedTokens;
    } else {
        return [];
    }
}

async function deleteOldTokens(tokenArray) {
    for (const token of tokenArray) {
        await fb.firestore().collection('devices').doc(token).delete();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...