HttpsError при вызове API Google Книг из функции Firebase Cloud

Я пытаюсь создать облачную функцию Firebase, которая выполняет поиск в API Google Книг.

export const searchBooksOnline = functions.https.onCall(
    async function(data: any, context: functions.https.CallableContext) {
        const query: string = data.query;
        console.log(`Received query loud and clear: ${query}`);
        try {
            const res = await fetch(`https://www.googleapis.com/books/v1/volumes?q=${query}&key=MY-API-KEY`);
            const json = await res.json();
            return json;
        } catch(err) {
            throw new functions.https.HttpsError(err.status, 'Failed to search books online');
        }
    }
);

Но всякий раз, когда я вызываю эту функцию из Javascript API, я получаю сообщение об ошибке:

Unhandled error Error: Unknown error code: undefined.
    at new HttpsError (/srv/node_modules/firebase-functions/lib/providers/https.js:95:19)
    at exports.searchBooksOnline (/srv/lib/books.js:42:15)
    at func (/srv/node_modules/firebase-functions/lib/providers/https.js:267:32)
    at <anonymous>
    at process._tickDomainCallback (internal/process/next_tick.js:229:7)

что для меня довольно загадочно. Я знаю, что функция вызывается правильно, потому что

  • Я вижу свою распечатку в журнале Cloud Functions "Отчет о полученном запросе:".

  • Когда я удаляю await fetch line и вернуть фиктивные данные, функция выполняется правильно.

Кроме того, я уверен, что вызов API работает, потому что, когда я копирую эти несколько строк для запуска непосредственно из консоли разработчика моего браузера, я получаю ожидаемый ответ API.

Я не уверен, чем отличается среда Cloud Functions, которая вызывает эту ошибку. (Я использую план Blaze, который должен позволить мне делать запросы на внешние сайты)

Надеюсь, что кто-нибудь поможет пролить свет на это!

(Я видел эту аналогичную проблему, но решение, примененное OP, для меня не имеет значения, у меня все еще такая же ошибка.)

2 ответа

Решение

Ответ от Doug Stevenson не решить эту проблему напрямую, но помог мне поставить диагноз:

Как только я исправил свой отчет HttpsError, как он предлагал, я попытался снова вызвать функцию, и на этот раз она выдала мне сообщение об ошибке: 'fetch' not defined. Оказывается,fetch который я успешно тестировал на клиентском JavaScript, изначально не реализован в NodeJS (который используют облачные функции).

Поэтому исправление заключалось в том, чтобы просто использовать другой метод для моего запроса API. В моем случае я решил использовать node-fetch, который реализует тот же интерфейс, что и JavaScript.fetch функция.

Итак, единственное изменение, которое мне нужно, чтобы все заработало, - это сделать

npm install node-fetch @types/node-fetch # the @types package needed for TypeScript

а потом

import fetch from 'node-fetch';

вверху моего кода.

Вызов API не выполняется, и вы неправильно используете functions.https.HttpsError. Согласно связанной документации API, первым аргументом конструктора должен быть объект типа FunctionsErrorCode, который должен быть одной из следующих строк:

"хорошо" | "отменен" | "неизвестно" | "неверный аргумент" | "крайний срок превышен" | "не найден" | "уже существует" | "отказано в разрешении" | "ресурс истощен" | "невыполненное предварительное условие" | "прервано" | "вне диапазона" | "нереализованный" | "внутренний" | "недоступен" | "потеря данных" | "неаутентифицированный"

Каждая из этих строк сопоставляется с кодом состояния HTTP, поэтому вам нужно будет решить, что вы на самом деле говорите клиенту. Вы, вероятно, захотите "внутренний", если вы просто хотите указать на сбой, который не может быть решен.

Другие вопросы по тегам