Non penso che sia una buona idea. Questo introduce l'accoppiamento in un modo molto non ovvio.
Considera una classe o un servizio. Ha compiti chiaramente definiti, i suoi metodi sono ben documentati, possono essere scambiati per qualcos'altro che ha la stessa interfaccia / contratto.
Supponiamo che incontri un'eccezione. Il servizio quindi può decidere se è recuperabile o meno. Questo, di per sé, va bene - se il servizio determina che un errore è recuperabile, dovrebbe ripristinarlo. Fine della storia.
La tua versione è abbastanza diversa. Nella tua domanda stai dicendo "Il servizio decide se la situazione è recuperabile dal chiamante ". Questo non va bene. Come lo sa il tuo servizio? Perché si preoccupa per chi lo chiama? È solo richiamabile da un'altra classe molto specifica?
Si parla di NPE come "errore generale". Potrebbe non essere. Potrebbe trattarsi di una configurazione errata o di dati errati inviati da un utente malintenzionato, non degli errori del programmatore (alcuni potrebbero obiettare che è un errore del programmatore non tenere conto di questa possibilità, ma non è questo il punto qui). Un'eccezione IO è un "errore generale"? Potrebbe significare che è necessario utilizzare una connessione di backup (ripristino semplice), oppure qualcuno ha strappato la scheda di rete da un sistema live (non così semplice da recuperare). Nessuna delle tue classi, salva l'ultimo gestore di eccezioni del thread, può decidere se l'app può recuperare da qualcosa o meno.
Se modifichi il codice del chiamante per gestire un tipo di eccezione che precedentemente era "irrecuperabile", come sai che è necessario modificare la parte che genera questa eccezione?
L'altro punto su cui non sono d'accordo è:
...inheriting from RuntimeException...
...should be passed back to the users of the API since they are expecting them...
Non penso che questo sia un buon uso di eccezioni non controllate.
Se si suppone che gli utenti dell'API si aspettino tali eccezioni, perché non farle controllare e farle rispettare? Quindi le eccezioni non verificate si propagheranno fino in fondo e potrebbero essere registrate in un modo specifico - ciò significherà esattamente ciò che si desidera - Nessuno del codice chiamante si aspettava o poteva gestire questa eccezione . Mentre le eccezioni "previste" dovranno essere gestite, anche se il codice chiamante insiste sul fatto che tutto ciò che fa è registrarlo (o addirittura inghiottirlo silenziosamente).
Questo ha il vantaggio in più che le modifiche API sono documentate! Puoi aggiungere più "eccezioni previste" se sono in esecuzione - e nessuno le noterà fino a quando non è già in diretta! Anche se una volta selezionato, non sarai in grado di compilare se non ti occupi della situazione.