Можно использоваться оба варианта. Часто, а точнее всегда, зависит от ситуации.
К примеру, вы хотите в репозитории сделать запрос на сторонний сервис (библиотекой got или axios). Ответ может быть какой угодно, включая ошибки построения неправильного запроса. В таком случае лучше обернуть данный блок кода в try/catch.
На все контроллеры, которые так или иначе взаимодествуют с бд, можно повесить try/catch на уровне контроллера.
В своих проектах, обычно, я оборачиваю все контроллеры в try/catch и передаю ошибку в последний middleware, где есть общий обрабочтик, который в зависимости от ошибки отдаёт пользователю соответсвующий ответ
Крайне рекомендую глянуть best practice для ноды, так как там как раз часто упоминается способ обработки ошибок.