Java >> Tutorial de Java >  >> Java

Por qué, cuándo y cómo implementar excepciones personalizadas en Java

Ya hablamos mucho sobre el manejo de excepciones en este blog y describimos las diferencias entre las excepciones verificadas y no verificadas, las mejores prácticas y los errores comunes. Si has leído estas publicaciones, probablemente hayas reconocido un patrón. Debe proporcionar información detallada sobre la situación que provocó la excepción y no debe eliminar nada que pueda ser útil para la persona que llama.

A menudo, puede lograrlo mediante el uso de excepciones estándar con buenos mensajes. La clase de excepción de Java describe el tipo de evento y el mensaje proporciona información detallada al respecto. Puede llevar este concepto un paso más allá usando una excepción personalizada.

Las excepciones personalizadas le brindan la flexibilidad de agregar atributos y métodos que no forman parte de una excepción de Java estándar. Estos pueden almacenar información adicional, como un código de error específico de la aplicación, o proporcionar métodos de utilidad que se pueden usar para manejar o presentar la excepción a un usuario.

Sugerencia:encuentre errores de aplicaciones y problemas de rendimiento al instante con Stackify Retrace. La solución de problemas y la optimización de su código son fáciles con errores integrados, registros e información sobre el rendimiento a nivel de código.

4 prácticas recomendadas para excepciones personalizadas

Hay 4 mejores prácticas generales que debe seguir cuando decida implementar una clase de excepción personalizada. Estas recomendaciones hacen que su código y API sean más fáciles de entender. También reducen la cantidad requerida de documentación. Eso vale la pena rápidamente si varios desarrolladores trabajan en la misma aplicación o biblioteca, nuevos miembros del equipo se unen a su proyecto o un proveedor de software externo decide usar sus API.

1. Proporcionar siempre un beneficio

Los ejemplos descritos anteriormente para atributos o métodos adicionales mostraron la intención de una excepción personalizada. Proporciona información o funcionalidad que no forma parte de las excepciones estándar de Java.

Esa es la esencia de la primera y más importante recomendación. De lo contrario, su excepción no brinda ningún beneficio en comparación con la gran cantidad de excepciones que ya proporciona el JDK.

Si no puede proporcionar ningún beneficio, es mejor que utilice una de las excepciones estándar, como UnsupportedOperationException o Excepción de argumento ilegal . Todos los desarrolladores de Java ya conocen estas excepciones. Eso hace que su código y API sean más fáciles de entender.

2. Siga la convención de nomenclatura

Cuando echa un vistazo a las clases de excepción proporcionadas por el JDK, reconoce rápidamente que todos sus nombres terminan con "Excepción". Esta convención de nomenclatura general se utiliza en todo el ecosistema de Java. Y su excepción personalizada también debería seguirlo.

3. Proporcione comentarios de Javadoc para su clase de excepción

No deberíamos necesitar hablar sobre esta mejor práctica, pero he visto demasiadas excepciones personalizadas sin ningún Javadoc.

Es una buena práctica general documentar todas las clases, campos, constructores y métodos de su API. Si alguna vez tuvo que usar una API no documentada, sabe exactamente por qué. Las API no documentadas son muy difíciles de usar.

Las clases de excepción pueden no ser la parte más obvia de su API, pero siguen siendo parte de ella. Tan pronto como uno de sus métodos orientados al cliente arroja una excepción, la clase de excepción se convierte en parte de la API. Eso implica que requiere documentación y un buen Javadoc.

El Javadoc debe describir el significado general de la excepción y las situaciones en las que podría ocurrir. El objetivo es ayudar a otros desarrolladores a comprender su API y evitar escenarios de error comunes.

/**
 * The MyBusinessException wraps all checked standard Java exception and enriches them with a custom error code.
 * You can use this code to retrieve localized error messages and to link to our online documentation.
 * 
 * @author TJanssen
 */
public class MyBusinessException extends Exception { ... }

4. Proporcione un constructor que establezca la causa

Muy a menudo, su código detecta una excepción estándar antes de lanzar su excepción personalizada. No debes ocultar este hecho. La excepción capturada generalmente contiene información esencial que necesitará para analizar un incidente de producción.

En el siguiente ejemplo, la NumberFormatException proporciona información detallada sobre el error. Perderá esta información si no la establece como la causa de MyBusinessException .

public void wrapException(String input) throws MyBusinessException {
	try {
		// do something
	} catch (NumberFormatException e) {
		throw new MyBusinessException("A message that describes the error.", e, ErrorCode.INVALID_PORT_CONFIGURATION);
	}
}

Excepción y Excepción de tiempo de ejecución proporcionar métodos constructores que acepten un Throwable que describe la causa de la excepción. Y su excepción debería hacer lo mismo. Debe implementar al menos un constructor que obtenga la causa Throwable como parámetro y lo establece en la superclase.

public class MyBusinessException extends Exception {

	public MyBusinessException(String message, Throwable cause, ErrorCode code) {
		super(message, cause);
		this.code = code;
	}

	...
}

Estas son las mejores prácticas más importantes para implementar una excepción personalizada. Si está buscando más consejos y recomendaciones, eche un vistazo a mis publicaciones que presentan 9 prácticas recomendadas y 7 errores comunes al trabajar con excepciones de Java.

Implementación de una excepción personalizada

Crear una excepción comprobada personalizada es simple. Ya viste varias partes cuando expliqué las 4 mejores prácticas para implementar excepciones personalizadas.

Cuando implementa una excepción marcada, debe extender la clase Excepción . Eso es lo único que debe hacer para crear una clase de excepción personalizada. Pero como expliqué anteriormente, también debe proporcionar un método constructor que establezca la excepción causante y brinde un beneficio en comparación con las excepciones estándar disponibles.

El siguiente ejemplo hace todo eso. Como puede ver, agregué un comentario de Javadoc que describe la excepción. También implementé un método constructor que establece la excepción causante en la superclase. Y para brindar un beneficio en comparación con las excepciones estándar, MyBusinessException utiliza una enumeración personalizada para almacenar un código de error que identifica el problema. Los clientes pueden usar el código de error para mostrar mensajes de error localizados o decirle al usuario que incluya este código en un ticket de soporte.

/**
 * The MyBusinessException wraps all checked standard Java exception and enriches them with a custom error code.
 * You can use this code to retrieve localized error messages and to link to our online documentation.
 * 
 * @author TJanssen
 */
public class MyBusinessException extends Exception {

	private static final long serialVersionUID = 7718828512143293558L;
	
	private final ErrorCode code;

	public MyBusinessException(ErrorCode code) {
		super();
		this.code = code;
	}

	public MyBusinessException(String message, Throwable cause, ErrorCode code) {
		super(message, cause);
		this.code = code;
	}

	public MyBusinessException(String message, ErrorCode code) {
		super(message);
		this.code = code;
	}

	public MyBusinessException(Throwable cause, ErrorCode code) {
		super(cause);
		this.code = code;
	}
	
	public ErrorCode getCode() {
		return this.code;
	}
}

Eso es todo lo que necesita hacer para implementar una excepción marcada personalizada. Ahora puede lanzar la MyBusinessException en su código, especifíquelo como parte de la firma de su método y manéjelo en una cláusula catch.

public void handleExceptionInOneBlock() {
	try {
		wrapException(new String("99999999"));
	} catch (MyBusinessException e) {
		// handle exception
		log.error(e);
	}
}

private void wrapException(String input) throws MyBusinessException {
	try {
		// do something
	} catch (NumberFormatException e) {
		throw new MyBusinessException("A message that describes the error.", e, ErrorCode.INVALID_PORT_CONFIGURATION);
	}
}

Implementación de una excepción no verificada

La implementación de una excepción no verificada personalizada es casi idéntica a una excepción verificada. Debes seguir las mismas recomendaciones que expliqué al principio de este post. La única diferencia es que una excepción no verificada tiene que extender RuntimeException en lugar de Excepción .

/**
 * The MyUncheckedBusinessException wraps all unchecked standard Java exception and enriches them with a custom error code.
 * You can use this code to retrieve localized error messages and to link to our online documentation.
 * 
 * @author TJanssen
 */
public class MyUncheckedBusinessException extends RuntimeException {

	private static final long serialVersionUID = -8460356990632230194L;

	private final ErrorCode code;

	public MyUncheckedBusinessException(ErrorCode code) {
		super();
		this.code = code;
	}

	public MyUncheckedBusinessException(String message, Throwable cause, ErrorCode code) {
		super(message, cause);
		this.code = code;
	}

	public MyUncheckedBusinessException(String message, ErrorCode code) {
		super(message);
		this.code = code;
	}

	public MyUncheckedBusinessException(Throwable cause, ErrorCode code) {
		super(cause);
		this.code = code;
	}
	
	public ErrorCode getCode() {
		return this.code;
	}
}

Puede utilizar MyUncheckedBusinessException de la misma manera que cualquier otra excepción no verificada. Puede incluirlo en su código y atraparlo en una cláusula de captura. Y puede pero no necesita especificar si su método lo arroja.

private void wrapException(String input) {
	try {
		// do something
	} catch (NumberFormatException e) {
		throw new MyUncheckedBusinessException("A message that describes the error.", e, ErrorCode.INVALID_PORT_CONFIGURATION);
	}
}

Resumen

Como se describe en esta publicación, la implementación de una excepción personalizada es fácil. Solo necesita extender Excepción para una excepción comprobada personalizada, o RuntimeException si es una excepción personalizada no verificada.

Además de eso, debe seguir algunas mejores prácticas. Hacen que su código sea más fácil de leer y su API más fácil de usar. Estas son las 4 mejores prácticas más importantes para las excepciones personalizadas en Java:

  • Solo debe implementar una excepción personalizada si proporciona un beneficio en comparación con las excepciones estándar de Java.
  • El nombre de clase de su excepción debe terminar con Excepción.
  • Si un método API especifica una excepción, la clase de excepción se convierte en parte de la API y debe documentarla.
  • Debe proporcionar un constructor que establezca la causa de la excepción.

Al utilizar Retrace APM con creación de perfiles de código, puede recopilar excepciones directamente desde Java, ¡sin cambios en el código!


Etiqueta Java