As soon as you have your services suddenly hooked up to something else - chron (or hangfire or whatever) jobs or a message bus - it gets a bit weird because your service layer thinks you're still responding to an HTTP request and whoever works on the service now has to think about HTTP as well which is pretty fucking bizarre to begin with.
And your unit tests for a business logic service method are gonna look at HTTP errors? It feels dirty, but not in a fun tap-your-nose way.
It's really not hard to just return errors relating to what actually happened (can't find user by id, user is blocked from logging in, whatever) and have the app's ingress points (API controllers, message handlers, job runners) decide how to surface that in a way that makes sense for the specific interface.
As soon as you have your services suddenly hooked up to something else - chron (or hangfire or whatever) jobs or a message bus - it gets a bit weird because your service layer thinks you're still responding to an HTTP request and whoever works on the service now has to think about HTTP as well which is pretty fucking bizarre to begin with.
And your unit tests for a business logic service method are gonna look at HTTP errors? It feels dirty, but not in a fun tap-your-nose way.
It's really not hard to just return errors relating to what actually happened (can't find user by id, user is blocked from logging in, whatever) and have the app's ingress points (API controllers, message handlers, job runners) decide how to surface that in a way that makes sense for the specific interface.