Hi Matt
Interesting question.
I don't know of a best practice, but as a starting place i would recommend you take a look at the connection manager the Fiori apps use.
The connection manager is set up once on app start and basically handles all ODataModel interactions. It uses the ODataModel broadcast events which normally get called last, therefore it is possible to overwrite the default behavior before the event is triggered eg using own success/error functions.
https://sapui5.hana.ondemand.com/resources/sap/ca/scfld/md/app/ConnectionManager-dbg.js
covers all the scenarios from Metadata failed (first sign of network issue), Metadata loaded, request sent, request completed, request failed etc.
manages the busy dialog between events
works well with Mock server also.
I have re-factored the standard code to be simpler, having less dependencies, it accepts only the component. From the component i can derive the service config from the metadata and determine whether in mock mode and how the router should react in case of message, eg continue on success, stop on error.
If your using $Batch calls some good code in various Fiori apps for handling those interactions.
happy to share a sanitized copy if it goes to help derive a best practice in this area
JSP