It seems like what you're encountering is a mixture of synchronous code, promises and async callbacks which have different error handling techniques.
One solution is to just do what you're doing, handle the different styles of errors individually, but this could get confusing and complicated. The other is to attempt to unify all such code into a single style, using simple abstractions to smooth them over.
I would personally attempt to normalize all of my calls as async callback style calls and then unify the error handling this way. For example it looks like you're using express middleware here, so I would pass all errors out and handle them in an error handler middleware.
import { auto, constant } from 'async'
const { assign } from Object
function sanitize (opts, callback) {
const { input } = opts
try {
sanitizeInput(input)
callback()
} catch (err) {
callback(assign(err, { status: 'sanitize_error', statusCode: 500 })
}
}
function createRow (opts, callback) {
const { santizie: input } = opts
dbCreateRowPromise(input)
.then(result => callback(null, result))
.catch(err => callback(assign(err, { status: 'create_row_error', statusCode: 500 }))
}
function my_function(req, res, input, next) {
const block = {
input: constant(input),
sanitize: ['input', sanitize],
createRow: ['sanitize', createRow]
}
auto(block, (err, result) => {
if (err) return next(err)
res.status(200).json({ status: 'ok' }))
})
}
function errorHandler(err, req, res) {
res.status(err.statusCode).json(err)
}