Comments 5
Спасибо.
После абзаца «Когда пользователь нажимает OK, его возраст присваивается userInput и передается в качестве аргумента функции из composeResolvers:» идёт почему-то повторение предыдущего кода. Видимо предполагался всё же первый вариант composeResolvers
После абзаца «Когда пользователь нажимает OK, его возраст присваивается userInput и передается в качестве аргумента функции из composeResolvers:» идёт почему-то повторение предыдущего кода. Видимо предполагался всё же первый вариант composeResolvers
async function fetchDogs(id) {
let result
if (typeof id === 'string') {
result = await api.fetchDogs(id)
} else if (typeof id === 'array') {
result = await Promise.all(id.map((str) => api.fetchDogs(id)))
} else {
throw new TypeError(
'callSomeApi only accepts a string or an array of strings',
)
}
return result
}
const params = { id: 'doggie123' }
let dogs
fetchDogs(params)
.then((dogs) => {
dogs = dogs
})
.catch((err) => {
if (err instanceof TypeError) {
dogs = Promise.resolve(fetchDogs(params.id))
} else {
throw err
}
})
Как я ненавижу функции которые могут принимать различные типы параметров. А тут в придачу оно еще и возвращает разные структуры. Тестировать такое просто одно удовольствие. И баги ловить когда этот код уже заюзали в десятках мест, и рефакторить… Мы такое на ревью не пропускаем. Ну сделай ты общую функцию которая работает с массивами, и оберни ее аккуратно функцией которая принимает один параметр. И чище, и без магии, и тестов меньше писать нужно.
Ну и на бэкенде далеко с этим не уедешь. Почти всегда нужно знать root cause, поэтому либо error chaining, либо копируем нужные данные с оригинальной ошибки. Ну и ошибки хттп клиентов ловим как можно раньше и оборачиваем в доменные ошибки, и обрабатываем их уже как можно позже, по возможности (как там у жавистов, кидай рано, обрабатывай поздно?).
Есть еще фишки с пробрасыванием контекста внутри ошибки, который помогают понять какой реквест был причиной (если говорим о веб сервере) или меседж (если воркер) если вдруг ошибка не обработалась и получили ексепшен.
Ну а в принципе работа с ошибками без тайп скрипта, то еще удовольствие… мы как те йожики с кактусом =)
class ArrayTooLongError extends Error {
name = 'ArrayTooLongError'
constructor(message) {
super(message)
}
}
// focus mocus
class ArrayTooLongError extends Error {
name = 'ArrayTooLongError'
}
class BadParametersError extends Error {
name = 'BadParametersError'
constructor(message) {
super(message)
}
get recommendation() {
return this._recommendation
}
set recommendation(recommendation) {
this._recommendation = recommendation
}
}
// focus mocus
class BadParametersError extends Error {
name = 'BadParametersError'
_recommendation = null
}
Дайте угадаю, до этого вы писали на Java | C#?
Есть неочевидный подводный камень при наследовании от Error в Typescript.
class MyError extends Error {}
const myError = new MyError;
console.log(myError instanceof MyError);
С target=es5
этот кода напечатает false
. https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work
Таким образом, идет лесом поддержка IE11 (так ей и надо) и тесты с Jest (который никак не научится нормально es modules поддерживать https://github.com/facebook/jest/issues/4842. кстати, будет ли работать, если запускать Jest с опциями target=es2017, module=commonjs
?).
В общем, будьте внимательны, тестируйте свой код :)
Sign up to leave a comment.
Лучшая практика обработки ошибок в современном JavaScript