Для получения данных из банка по сети есть стандартизированный async Fetch API.
Рекомендуется использовать неглобальный декоратор fetch, который:
- автоматически логирует запросы
- позволяет задать parse/stringify функции для преобразования сырых данных в объекты
- позволяет задать sanitizeRequestLog/sanitizeResponseLog маски для скрытия приватных данных из логов
Так же есть fetchJson, который автоматически преобразует сырые данные в json и обратно.
По умолчанию ответы от сервера преобразуются в строку прежде чем попадают в parse. Чтобы получить непосредственно байты надо вызывать fetch(url, { binaryResponse: true }).
Для логирования есть знакомый всем стандартизированный Console API.
Все вызовы console на мобильных устройствах превращаются в текст лога. Вместе с текстом, как и везде, можно передавать структуры данных любой глубины.
Например,
console.log('что-то тут не так', { deadBodies: 999 })
напишет в лог работы плагина
[log] что-то тут не так { deadBodies: 999 }
Логи с мобильных устройств пользователи отправляют в случае, если что-то пошло не так (например, плагин выбросил ошибку), или специально (если поведение плагина некорректное, в настройках плагина есть кнопочка "отправить лог последней синхронизации".
console.assert(condition, ...args)
ведёт себя везде так, как в node.js
(бросает AssertionError если значение condition
ложно) во всех окружениях,
так что можно его смело использовать для строгих утверждений.
Вызов
console.assert(response.status === 200, 'Не удалось получить транзакции', { response })
прервёт выполнение и запишет в лог
Не удалось получить транзакции { response: { status: ... } }
а пользователь увидит на UI сообщение
Ошибка в импорте из банка. Отправьте отчёт, чтобы мы смогли найти и исправить ошибку.
с предложением отправить лог разработчику.
Для того, чтобы прервать выполнение, достаточно выбросить любое исключение.
throw new Error("Всё не так =[");
Текст ошибки пользователю не показывается, а только логируется. Пользователь увидит на UI сообщение
Ошибка в импорте из банка. Отправьте отчёт, чтобы мы смогли найти и исправить ошибку.
с предложением отправить лог разработчику.
Также есть возможность подсказать мобильному приложению, как обрабатывать
ошибку, используя ZPAPIError
как конструктор ошибки:
ZPAPIError(message: String?, logIsNotImportant: Bool?, forcePluginReinstall: Bool?)
Рекомендуется использовать готовые классы ошибок для случаев:
- Пользователь неправильно ввёл логин или пароль.
throw new InvalidLoginOrPasswordError()
- Пользователь неправильно ввёл пароль, возможно это был пин-код от приложения банка вместо нужного пароля от интернет-банка.
throw new PinCodeInsteadOfPasswordError()
- Пользователь неправильно заполнил прочие настройки плагина.
throw new InvalidPreferencesError()
- Пользователь ввел неверный код подтверждения.
throw new InvalidOtpCodeError()
- Пользователь не завершил предыдущую сессию в банке, и поэтому банк не пускает плагин.
throw new PreviousSessionNotClosedError()
- Ошибка временная (сеть пропала, уборщица уронила сервер банка) и мы явно об этом знаем, и ничего не можем с этим поделать (пробовали делать retry), и просто не хотим, чтобы пользователь слал нам такие ошибки.
throw new TemporaryUnavailableError()
- Банк хочет что-то важное сказать пользователю, что пользователь должен поправить.
throw new BankMessageError(message)
Одним из аргументов scrape из index.js является preferences - настройки плагина, которые были заполнены пользователем.
Ключами объекта являются значения key
из
preferences.xml
// При условии наличия в preferences.xml:
// <EditTextPreference key="login" ... />
// <EditTextPreference key="password" ... />
// Получаем так:
const { login, password } = preferences
Например, для аутентификации понадобился SMS код, который банк прислал владельцу аккаунта.
const smsCode = await ZenMoney.readLine("Введите код из СМС сообщения");
if (!smsCode) {
throw new Error("Без SMS-кода не смогу =[");
}
Иногда может понадобиться сохранение данных между несколькими вызовами плагина. Примером таких данных может быть accessToken банка, выданный банком в ответ на успешное подтверждение выданного пользователю SMS-кода (мы же не хотим, чтобы при каждом запуске синхронизации пользователь вводил значение из SMS?).
ZenMoney.setData(key: String, value: Any?)
Удалить значение по ключу можно при помощи вызова
ZenMoney.setData(key, null)
.
ZenMoney.getData(key: String, defaultValue: Any?) -> Any?
ZenMoney.clearData()
ZenMoney.saveData()
Физически данные сохраняются или очищаются только после вызова
ZenMoney.saveData()
.
ZenMoney.isAccountSkipped(id: String) -> Bool
Метод существует для того, чтобы не выполнять ненужную работу по выгрузке данных, которые решил пропустить пользователь.
Пропущенными счётами можно управлять в настройках подключения.
Необходимо его использовать для фильтрации полученных из банка счетов, до того как запрашивать по ним транзакции.