¡Advertencia! ¡El programador de C ++ que viene aquí con ideas posiblemente diferentes de cómo se debe hacer el manejo de excepciones tratando de responder una pregunta que ciertamente es sobre otro lenguaje!
Ante esta idea:
Por ejemplo, imagine que tenemos un recurso de recuperación, que realiza una solicitud HTTP y devuelve los datos recuperados. Y en lugar de errores como ServiceTemporaryUnavailable o RateLimitExceeded, solo plantearíamos un RetryableError sugiriendo al consumidor que debería volver a intentar la solicitud y no preocuparse por fallas específicas.
... una cosa que sugeriría es que puede estar mezclando preocupaciones de informar un error con cursos de acción para responder de una manera que pueda degradar la generalidad de su código o requerir muchos "puntos de traducción" para las excepciones .
Por ejemplo, si modelo una transacción que implica cargar un archivo, podría fallar por varias razones. Quizás cargar el archivo implica cargar un complemento que no existe en la máquina del usuario. Quizás el archivo simplemente está dañado y encontramos un error al analizarlo.
Pase lo que pase, digamos que el curso de acción es informar lo que sucedió al usuario y preguntarle qué quiere hacer al respecto ("reintentar, cargar otro archivo, cancelar").
Lanzador contra receptor
Ese curso de acción se aplica independientemente del tipo de error que encontramos en este caso. No está integrado en la idea general de un error de análisis, no está integrado en la idea general de no cargar un complemento. Está incrustado en la idea de encontrar tales errores durante el contexto preciso de cargar un archivo (la combinación de cargar un archivo y fallar). Por lo general, lo veo, hablando en términos crudos, como la catcher'sresponsabilidad de determinar el curso de acción en respuesta a una excepción lanzada (por ejemplo, preguntar al usuario con opciones), no el thrower's.
Dicho de otra manera, los sitios cuyas throwexcepciones generalmente carecen de este tipo de información contextual, especialmente si las funciones que arrojan son generalmente aplicables. Incluso en un contexto totalmente desgeneralizado cuando tienen esta información, terminas arrinconándote en términos de comportamiento de recuperación al insertarlo en el throwsitio. Los sitios que catchgeneralmente tienen la mayor cantidad de información disponible para determinar un curso de acción y le brindan un lugar central para modificar si ese curso de acción alguna vez cambia para esa transacción dada.
Cuando comienzas a intentar lanzar excepciones que ya no informan qué está mal, sino que intentas determinar qué hacer, eso podría degradar la generalidad y flexibilidad de tu código. Un error de análisis no siempre debe conducir a este tipo de mensaje, varía según el contexto en el que se produce dicha excepción (la transacción en la que se produjo).
El lanzador ciego
Solo en general, gran parte del diseño del manejo de excepciones a menudo gira en torno a la idea de un lanzador ciego. No sabe cómo se detectará la excepción ni dónde. Lo mismo se aplica incluso a las formas más antiguas de recuperación de errores utilizando la propagación manual de errores. Los sitios que encuentran errores no incluyen un curso de acción del usuario, solo incrustan la información mínima para informar qué tipo de error se encontró.
Responsabilidades invertidas y generalización del receptor
Al pensar en esto con más cuidado, estaba tratando de imaginar el tipo de base de código donde esto podría convertirse en una tentación. Mi imaginación (posiblemente equivocada) es que su equipo todavía está desempeñando el papel de "consumidor" aquí e implementando la mayor parte del código de llamada también. Quizás tenga muchas transacciones dispares (muchos trybloques) que pueden encontrarse con los mismos conjuntos de errores, y todos deberían, desde una perspectiva de diseño, conducir a un curso uniforme de acción de recuperación.
Teniendo en cuenta los sabios consejos de una Lightness Races in Orbit'sbuena respuesta (que creo que realmente proviene de una mentalidad avanzada orientada a la biblioteca), aún podría sentirse tentado a lanzar excepciones de "qué hacer", solo más cerca del sitio de recuperación de transacciones.
Podría ser posible encontrar aquí un sitio intermediario y común de manejo de transacciones que realmente centralice las preocupaciones de "qué hacer", pero aún dentro del contexto de la captura.

Esto solo se aplicaría si puede diseñar algún tipo de función general que utilicen todas estas transacciones externas (por ejemplo: una función que ingresa otra función para llamar o una clase base de transacción abstracta con comportamiento reemplazable que modela este sitio de transacciones intermedias que realiza la captura sofisticada )
Sin embargo, ese podría ser responsable de centralizar el curso de acción del usuario en respuesta a una variedad de posibles errores, y aún dentro del contexto de atrapar en lugar de tirar. Ejemplo simple (pseudocódigo de Python-ish, y no soy un desarrollador experimentado de Python en lo más mínimo, por lo que podría haber una forma más idiomática de hacerlo):
def general_catcher(task):
try:
task()
except SomeError1:
# do some uniformly-designed recovery stuff here
except SomeError2:
# do some other uniformly-designed recovery stuff here
...
[Ojalá con un nombre mejor que general_catcher]. En este ejemplo, puede pasar una función que contiene qué tarea realizar, pero aún así beneficiarse del comportamiento de captura generalizado / unificado para todos los tipos de excepciones que le interesan, y continuar extendiendo o modificando la parte "qué hacer" le gusta desde esta ubicación central y aún dentro de un catchcontexto en el que esto generalmente se fomenta. Lo mejor de todo es que podemos evitar que los sitios de lanzamiento se preocupen por "qué hacer" (preservando la noción de "lanzador ciego").
Si no encuentra ninguna de estas sugerencias útiles aquí y hay una fuerte tentación de lanzar excepciones de "qué hacer" de todos modos, tenga en cuenta que esto es muy anti-idiomático por lo menos, y también puede desalentar una mentalidad generalizada.