Или есть другой способ вызвать ошибки в функциональном коде?
Ошибки выбрасывания скважин являются побочным эффектом и поэтому полностью не функционируют. Тем не менее, Express использует их, чтобы заставить сервер реагировать определенным образом, так что это немного вне вашего контроля. Вам придется throw
в какой-то момент ...
Я согласен, что "хитрость" состоит в том, чтобы написать обработчик динамического маршрута, но я думаю, что я бы немного изменил его по сравнению с тем, как @eol написал их
код x > 5
является частью вашей лямбды в вашем маршруте, но сообщение об ошибке x should be greater than 5
не настраивается. Если лямбда изменится на «1014», сообщение об ошибке не будет иметь смысла
оператор с одной ветвью if
является ошибочным и требует undefined
для неиспользуемой ветви - это бородавка в коде. Может быть, переместить Error
в эту позицию?
Вот как может выглядеть исправленный обработчик -
const serveJson = (cb) => (req, res, next) => {
const x = Number(req.query.x)
const y = Number(req.query.y)
const data = cb(x, y)
if (data instanceof Error)
throw data
else
res.json(data)
}
app.get('/test', serveJson((x, y) =>
x > 5
? { x: x + y }
: Error(`value for x (${x}) cannot exceed 5`)
))
Проблемы остаются. serveJson
не является достаточно универсальным, поскольку он всегда запрашивает параметры x
и y
, что заставляет нас задаться вопросом, почему это вообще отдельная функция. Сколько маршрутов вам потребуется, чтобы определить, что именно для чтения только параметры запроса x
и y
?
Вы бы использовали это так? Я не знаю, это похоже на досягаемость -
app.get('/add', serveJson((x, y) =>
x > 5
? { result: x + y }
: Error(`value for x (${x}) cannot exceed 5`)
))
app.get('/mult', serveJson((x, y) =>
x > 10
? { result: x * y }
: Error(`value for x (${x}) cannot exceed 10`)
))
app.get('/divide', serveJson((x, y) =>
x !== 0
? { result: x / y }
: Error(`divisor cannot be zero`)
))
У вас действительно будет много мест, где вы можете использовать serveJson
, как это? Это кажется маловероятным, но чтобы победить мертвую лошадь, давайте попробуем сделать serveJson
более гибким, позволив нам указать параметры, с которыми мы хотим работать. Это все исправит, верно?
const serveJson = (params, cb) => (req, res, next) => {
const data = cb(...params.map(p => Number(req.query[p])))
if (data instanceof Error)
throw data
else
res.json(data)
}
app.get('/test', serveJson(['x', 'y'], (x, y) =>
x > 5
? { result: x + y }
: Error(`value for x (${x}) cannot exceed 5`)
))
Это будет считаться более функциональным, поскольку все взаимосвязанные части являются настраиваемыми аргументами на сайте вызова serveJson
. Но у вас все еще есть огромная проблема - он предполагает, что все параметры являются числами, и пытается их соответствующим образом проанализировать / проверить.
Конечно, вы могли бы продолжать работать над этим и придумать что-нибудь -
app.get('/test/, serveJson({ x: Number, y: Number, z: String }, (x, y, z) =>
// ...
))
Но обратите внимание, как все внешние спецификации становятся большими. Как будто было бы проще вообще пропустить serveJson
. Нет скрытых намерений со 100% гибкостью -
app.get('/test', (req, res, next) => {
const x = Number (req.params.x)
const y = Number (req.params.y)
if (x > 5)
res.json({ result: x + y })
else
throw Error(`value for x (${x}) cannot exceed 5`)
})
В конце всего этого вы попросили волшебную пулю, которая просто не может существовать. По крайней мере, когда вы начинаете представлять нетривиальные случаи, в отличие от псевдокода, предоставленного в вашем OP.
Пожалуйста, расскажите больше о вашей программе. Я думаю, что каждый сможет помочь вам более эффективно.