Manejo de errores. Eduardo Ostertag Jenkins, Ph.D. OBCOM INGENIERIA S.A. (Chile) Eduardo.Ostertag@obcom.cl



Documentos relacionados
Uso de excepciones en Java

Programación Orientada a Objetos. Java: Excepciones

Introducción - por qué usarlas?(1)

Programación Orientada a Objetos. Java: Excepciones

TUTORIAL DESARROLLO DE APLICACIONES PARA EVOLUTION CON MS ACCESS

Los paquetes tienen dos partes: una especificación y un cuerpo que están almacenados por separado en la base de datos.

Oracle básico (IV): Programación en PL/SQL

BASES DE DATOS EN VISUAL BASIC ACCESS + SQL

GUÍA DE TRABAJO N 11 LENGUAJE C# Programación de Software Articulación SENA Grado 10 Ing. Néstor Raúl Suarez Perpiñan Página 2 de 11

Tema 14: Excepciones

Enlaces relacionados:

Un ejemplo teórico de trigger podría ser éste:

BASES DE DATOS AVANZADAS Transacciones en MYSQL

JDBC. Una mini-introducci. introducción

El primer paso a realizar es crear la referencia JNDI para el origen de datos en el servidor local TomCat.

Práctica 4: Java Remote Method Invocation (RMI)

En este ejemplo también vamos a crear la capa Entidades que va a servir para modelar nuestra base de datos.

GUÍA DE TRABAJO GRADO 11 Programación de. Software Ing. Néstor Raúl Suarez Perpiñan Página 1 de 6

Oracle 12c DISEÑO Y PROGRAMACIÓN

Práctica sobre compartición de instancias remotas.

Tema: Mineria de datos.

Manejo de Errores Ejercicio Facturas

SOLUCION PARCIAL TASK SCHEDULER. Task Scheduler

Modulo 1 El lenguaje Java

CURSORES EN SQL SERVER

PL/SQL. Con PL/SQL vamos a poder programar las unidades de programa de la base de datos Oracle:

Programación en Java. Programación en OO

Procedimientos, Funciones, Trigger y Cursores en ORACLE

Universidad ORT - Arquitectura de Software. Requisitos

Oracle Básico PL/SQL

GUÍA DE TRABAJO GRADO 11. Articulación SENA Programación de Software Ing. Néstor Raúl Suarez Perpiñan Página 1 de 6

JSP. MSc. Daniel Alejandro Yucra Sotomayor Pag Web Services. Laboratorio Nro. 11. Web Services con JAX-WS con MySQL. I. Competencia General:

%& %)& '$!%*+ $, %%%&$ %%

Día 2: Utilizando controles de datos en Visual Studio 2008.

1

myappgen Usted Construye la aplicación mientras la ejecuta

Elementos léxicos del lenguaje de programación Java

Practica 11: Conexión de Java con Bases de datos Access

Convirtiendo arboles de expresión lambda en diferentes strings.

Tutorial para la creación de Bots de NTRadmin

EXCEPCIONES EN JAVA. Las sentencias que tratan las excepciones son try y catch. La sintaxis es:

Administración Básica de Oracle9i.

Patrones para persistencia (I) Ingeniería del Software II

Aplicaciones de las vistas Concepto de vista Vistas en SQL Vistas en SQL.

Disparadores en Oracle (Ejemplos Prácticos)

Lic. Vladimir Cotaquispe Gutierrez PROGRAMACIÓN PL/SQL I - 1. Copyright 2008, Oracle. All rights reserved.

Guía práctica de introducción básica a JDBC

GESTIÓN DE EXCEPCIONES EN JAVA. CAPTURA CON BLOQUES TRY CATCH Y FINALLY. EJEMPLOS RESUELTOS. (CU00927C)

- Bases de Datos - - Diseño Físico - Luis D. García

Bases de Datos SQL 1 SQL. Jorge Pérez R. Universidad de Talca, II Semestre 2006

Solución al Examen de Prácticas de Programación (Ingeniería Informática)

2. Estructura de un programa en Java

Introducción a Java LSUB. 15 de enero de 2015 GSYC

EXAMEN FINAL Metodología y Programación Orientada a Objetos. Curso Cuatrimestre de otoño. 17 de Enero de 2011

Enviar Felicitación Navideña por con Off. 2007

Primer Parcial Septiembre 5 de 2009

Estándares para la construcción de Sentencias SQL

Tutorial : Hacer Combos Dependientes tipo Departamento Ciudad en ASP. Net

USANDO SERVLETS EN UN SERVIDOR WEB RESIN

Programación Orientada a Objetos con Java

Tablas y Campos Nuevos

Excepciones. Gonzalo Méndez - Dpto. Ingeniería de Software e Inteligencia Artificial. Excepciones

Imprimir PDF en WebDynpro para JAVA sin utilizar Interactive Forms en llamadas RFC.

Excepciones. Excepciones

1. Creación del repositorio

Laboratorios de BASES DE DATOS. (I.T. Informática)

RESUMEN DE CONCEPTOS BASICOS DE PROGRAMACION JAVA

Un breve resumen del lenguaje Java

Formato para prácticas de laboratorio

Programación Concurrente en Java

Control de errores en Visual Basic.NET

OBCOM MetaServer Instalació n y Cónfiguració n

Índice. Introducción Qué es? Conceptos clave Instalación Ejemplo Hola Mundo Procedimientos Almacenados

Iniciando con Oracle. Índice de contenido. Ingresando a Oracle. Cambiando Su Contraseña. Ingresando un Comando SQL en SQL*Plus

SQL y XML en Oracle XE 11g. Laboratorio de Bases de datos Jonathan Medina Gómez

Programación Orientada a Objetos II. La Plataforma JDBC

Administradores de Bases de Datos Studio.NET 2005 Y SQL Server Barrios

1. Posicionarse en la vista Services y seleccionar el ítem Servers. En el menú contextual del Mouse seleccionar la opción Add Server

INSTITUTO TECNOLÓGICO DE NUEVO LAREDO ING. EN SISTEMAS COMPUTACIONALES

Tutorial Básico de vbscript

Tema 2. El lenguaje de programación Java (Parte 1)

Formato para prácticas de laboratorio

Resolver triángulos en Visual Basic. Parte 3/3

Base de datos Procedimientos Almacenados y Funciones

GUIA DE LABORATORIO N 9 B. (000Webhost Php- Para desarrollar en casa)

myappgen Usted Construye la aplicación mientras la ejecuta

UNIVERSIDAD DE SEVILLA PRÁCTICAS DE LABORATORIO ANÁLISIS SINTÁCTICO (1) LENGUAJES FORMALES Y AUTÓMATAS CURSO 2006/2007

Estándar de desarrollo de aplicaciones del Govern de les Illes Balears

UNIVERSIDAD DEL ISTMO CAMPUS IXTEPEC LIC. INFORMATICA GRUPO 508 PROCEDIMIENTOS ALMACENADOS EN SQL SERVER 2000

Principales rutinas de mantenimiento

Programación Orientada a Objetos en Visual Basic

TUTORIAL OPERADOR CUBE

VB y List & Label WhitePaper Junio de 2007

Manual de JSP con MySQL

Conexión de Mysql con NetBeans

Manejo de datos BLOB con PHP y MySQL

De uno a uno : Ejemplo de una llave primaria a otra llave primaria De uno a muchos : Ejemplo de una llave primaria a una Regular o Foránea.

Desarrollo Cobol/DB2

Desarrollo de Servicios Web con JBuilder

UNIVERSIDAD LIBRE DE COLOMBIA FACULTAD INGENIERIA DE SISTEMAS ELECTIVA TECNICA II.NET Y SQL SERVER

Transcripción:

Manejo de errores Eduardo Ostertag Jenkins, Ph.D. OBCOM INGENIERIA S.A. (Chile) Eduardo.Ostertag@obcom.cl

Temario Siempre liberar los recursos Errores en Java Sólo un mensaje por error Errores en Visual Basic 6 Errores en ASP y VBScript Errores en Oracle PL/SQL

Siempre liberar los recursos

Está liberando siempre los recursos? public Properties leerpropiedades(string archivo) throws FileNotFoundException, IOException { Properties propiedades = new Properties(); FileInputStream fis = new FileInputStream(archivo); propiedades.load(fis); fis.close(); return propiedades; Se ejecuta siempre este close?

Siempre libere los recursos con finally public Properties leerpropiedades(string archivo) throws FileNotFoundException, IOException { Properties propiedades = new Properties(); FileInputStream fis = new FileInputStream(archivo); try { propiedades.load(fis); finally { fis.close(); return propiedades;

Programó correctamente el finally? public BigDecimal obtenervaloruf(datasource datasource, Date fecha) throws SQLException { Connection conn = null; CallableStatement call = null; try { conn = datasource.getconnection(); call = conn.preparecall("{call ObtenerValorUF(?,?)"); call.setdate(1, fecha); call.registeroutparameter(2, Types.DECIMAL); call.execute(); return call.getbigdecimal(2); finally { if (call!= null) call.close(); if (conn!= null) conn.close(); Se ejecuta siempre este close?

Un finally debe liberar sólo un recurso public BigDecimal obtenervaloruf(datasource datasource, Date fecha) throws SQLException { Connection conn = datasource.getconnection(); try { CallableStatement call = conn.preparecall("{call (?,?)"); try { call.setdate(1, fecha); call.registeroutparameter(2, Types.DECIMAL); call.execute(); return call.getbigdecimal(2); finally { call.close(); finally { conn.close();

Try-With-Resources (para Java 7) public BigDecimal obtenervaloruf(datasource datasource, Date fecha) throws SQLException { try (Connection conn = datasource.getconnection()) { try (CallableStatement call = conn.preparecall("{ (?,?)")) { call.setdate(1, fecha); call.registeroutparameter(2, Types.DECIMAL); call.execute(); return call.getbigdecimal(2); Un try-with-resources hace close automáticamente El recurso debe implementar AutoCloseable o Closeable Excepciones en close implícitos se llaman Suppressed

Comentarios y sugerencias de finally Un finally se ejecuta siempre; da lo mismo cómo terminó el try : normal, return, error Java garantiza que se ejecutará la primera sentencia del finally. Las otras puede que no se ejecuten debido a excepciones Se recomienda que un finally libere sólo un recurso (que tenga sólo una sentencia) Para varios recursos, se recomienda que anide los finally uno dentro de otro

Ahora que todo está claro una pregunta Qué valor retorna el método getnombre? public class Ejemplo { private String nombre; public String getnombre() { try { nombre = "Pepe Pótamo"; return nombre; finally { nombre = null;

Errores en Java

Tipos de excepciones en Java Throwable Exception checked RuntimeException unchecked NullPointerException FileNotFoundException SQLException Error VirtualMachineError

Ejemplo: leer propiedades de un archivo public Properties leerpropiedades(string archivo) throws FileNotFoundException, IOException { // Verificamos archivo if (archivo == null) throw new NullPointerException("archivo es null"); // Abrimos archivo y cargamos las propiedades Properties propiedades = new Properties(); FileInputStream fis = new FileInputStream(archivo); try { propiedades.load(fis); finally { fis.close(); // Retornamos propiedades return propiedades;

Tragarse (perder) las excepciones public String obtenernombreusuario(string archivo) { try { Properties props = leerpropiedades(archivo); return props.getproperty("nombre.usuario"); catch (Exception ex) { ex.printstacktrace(); // esto es muy return null; // asqueroso! Perdemos el detalle de la excepción (mensaje, stack, causa), y retornamos un valor especial El que llama debe revisar el valor retornado, y si se olvida, no se entera que ocurrió un error

Declarar cada excepción checked public String obtenernombreusuario(string archivo) throws FileNotFoundException, IOException { Properties props = leerpropiedades(archivo); return props.getproperty("nombre.usuario"); El que llama puede usar catch selectivos Las excepciones dan detalles de implementación: encapsulación pobre y posible acoplamiento No podemos agregar y/o eliminar excepciones de la lista debido a cambios en la implementación

Declarar una sola excepción genérica public String obtenernombreusuario(string archivo) throws Exception { Properties props = leerpropiedades(archivo); return props.getproperty("nombre.usuario"); No se declaran las excepciones específicas: no se puede usar catch selectivos Podemos cambiar la implementación interna sin tener que cambiar la declaración del método

Convertir checked en unchecked public String obtenernombreusuario(string archivo) { try { Properties props = leerpropiedades(archivo); return props.getproperty("nombre.usuario"); catch (Exception ex) { throw new RuntimeException(ex); Incluye todo el detalle de la excepción: mensaje, stack y causa del error Podemos cambiar la implementación interna sin tener que cambiar la declaración del método

Disparar unchecked con valor agregado public String obtenernombreusuario(string archivo) { try { Properties props = leerpropiedades(archivo); return props.getproperty("nombre.usuario"); catch (Exception ex) { throw new RuntimeException( "No se pudo obtener nombre del usuario" + " desde el archivo: " + archivo, ex); Con todas las ventajas de la técnica anterior Entregamos el detalle del contexto del error (en este ejemplo: el nombre del archivo)

Disparar unchecked personalizada public String obtenernombreusuario(string archivo) { try { Properties props = leerpropiedades(archivo); return props.getproperty("nombre.usuario"); catch (Exception ex) { throw new ObtenerException( "No se pudo obtener nombre del usuario" + " desde el archivo: " + archivo, ex); Con todas las ventajas de la técnica anterior Podemos atrapar la excepción con un catch específico sin confundir con otras excepciones

Excepciones personalizadas (custom) public class ObtenerException extends RuntimeException { public ObtenerException(String message) { super(message); public ObtenerException(String message, Throwable cause) { super(message, cause); Definir una excepción personalizada requiere de programación muy, pero muy simple Pueden ser checked si extienden Exception, o ser unchecked si extienden RuntimeException

Detalles Stack Trace de una excepción Exception in thread "main" java.sql.sqlexception: Could not read database at cl.obcom.example.suppressed.donothinggood(suppressed.java:26) at cl.obcom.example.suppressed.main(suppressed.java:38) Caused by: java.lang.illegalargumentexception: Supplied argument is invalid at cl.obcom.example.naughty.donothinggood(naughty.java:25) at cl.obcom.example.suppressed.donothinggood(suppressed.java:24)... 1 more Suppressed: java.lang.illegalstateexception: Not connected to database at cl.obcom.example.naughty.close(naughty.java:37) at cl.obcom.example.suppressed.donothinggood(suppressed.java:25)... 1 more Nombre de la excepción: mensaje (si tiene) at nombre de clase. método (archivo:línea) Caused (Chained) y Suppressed (relación)... 1 more (líneas repetidas)

Sólo un mensaje por error

Logging en cuanto ocurre la excepción public String obtenernombreusuario(string archivo) throws Exception { try { Properties props = leerpropiedades(archivo); return props.getproperty("nombre.usuario"); catch (Exception ex) { ex.printstacktrace(); // logging throw ex; En cuanto ocurre un error, se hace logging de la info de la excepción (mensaje, stack, causa) Logging: System.out, printstacktrace, log4j,

Error muchos mensajes de logging Método fuera de su control try { b(); catch (Exception ex) { ex.printstacktrace(); a El método d dispara una excepción, y se hace logging en c, b y a try { c(); catch (Exception ex) { ex.printstacktrace(); throw ex; b try { d(); catch (Exception ex) { ex.printstacktrace(); throw ex; c

Error un solo mensaje de logging Método fuera de su control try { b(); catch (Exception ex) { ex.printstacktrace(); a El método d dispara una excepción, y se hace logging una sola vez en a try { c(); catch (Exception ex) { throw new Exception(" ", ex); b try { d(); catch (Exception ex) { throw new Exception(" ", ex); c

Mensaje de DEBUG java.util.logging import java.util.logging.*; private static final Logger logger = Logger.getLogger(EstaClase.class.getName()); try { method( ); catch (Exception ex) { logger.log(level.fine, "mensaje ", ex); throw new Exception("mensaje ", ex); Se genera un mensaje de nivel FINE (DEBUG) Luego se dispara la excepción con valor agregado

Niveles mensajes java.util.logging OFF: ningún mensaje ( ) SEVERE: mensajes severos (1000) WARNING: mensajes de advertencia (900) INFO: mensajes de información (800) CONFIG: mensaje de configuración (700) FINE: mensajes de seguimiento (500) FINER: mensajes de seguimiento fino (400) FINEST: mensajes de seguimiento muy fino (300) ALL: todos los mensajes (- )

Error un ERROR y cero o más FINE Método fuera de su control try { b(); catch (Exception ex) { logger.log(level.error, ); a El método d dispara una excepción, y se hace logging nivel ERROR sólo en a. Los métodos c y b pueden hacer logging nivel FINE. try { c(); catch (Exception ex) { logger.log(level.fine, ); throw new Exception(" ", ex); b try { d(); catch (Exception ex) { logger.log(level.fine, ); throw new Exception(" ", ex); c

Error un solo mensaje de logging Regla: dispare (throw) una excepción si ella podrá ser atrapada (catch) en uno de sus métodos, de lo contrario haga logging Debe hacer logging cuando vaya a perder control de la excepción. Por ejemplo en: Método main o run de una hebra (Thread) Método en página JSP o acción de Struts Método de un Servicio Web o de un MDB

Errores en Visual Basic 6

VB6: disparar error con valor agregado Private Sub MostrarUsuario(ByVal RutUsuario As String) '++ ' Ejemplo de disparar error con valor agregado. '-- 'Definir error handler On Error GoTo ErrorHandler aquí se muestra al usuario 'Salida normal Exit Sub ErrorHandler: Err.Raise Err.Number, "MostrarUsuario:" & Err.Source, _ "No se pudo mostrar al usuario: " & RutUsuario & _ vbcrlf & Err.Description End Sub

VB6: liberar recurso y disparar error Private Sub MostrarUsuario(ByVal RutUsuario As String) '++ ' Ejemplo de liberar recurso antes de disparar error. '-- Dim ErrNumber As Long Dim ErrSource As String Dim ErrString As String 'Definir error handler On Error GoTo ErrorHandler aquí se muestra al usuario 'Salida normal Exit Sub ErrorHandler: ErrNumber = Err.Number ErrSource = Err.Source ErrString = Err.Description Call LiberarRecurso 'Puede cambiar objeto "Err" Err.Raise ErrNumber, "MostrarUsuario:" & ErrSource, _ "No se pudo mostrar al usuario: " & RutUsuario & _ vbcrlf & ErrString End Sub

VB6: registrar y mostrar un error (I) Private Sub CmdAceptar_Click() '++ ' Ejemplo de registrar y mostrar error. '-- 'Definir error handler On Error GoTo ErrorHandler aquí se muestra al usuario 'Salida normal Exit Sub ErrorHandler: LogMsgBox Err.Number, "CmdAccept:" & Err.Source, _ "No se pudo mostrar al usuario: " & RutUsuario & _ vbcrlf & Err.Description End Sub

VB6: registrar y mostrar un error (II) Public Sub LogMsgBox( _ ByVal ErrNumber As Long, _ ByVal ErrSource As String, _ ByVal ErrString As String) '++ ' Registra y muestra un error. '-- 'Ignoramos los errores On Error Resume Next 'Registramos el error en el "Visor de eventos" Call AppLogEvent(ErrNumber, ErrSource, ErrString) End Sub 'Mostramos el error al usuario MsgBox ErrString, Me.Caption, vbexclamation

VB6: registrar y mostrar un error (III) Public Sub AppLogEvent( _ ByVal ErrNumber As Long, _ ByVal ErrSource As String, _ ByVal ErrString As String) '++ ' Registra un error formateado en el "Visor de eventos". '-- Dim Mensaje As String 'Ignoramos los errores On Error Resume Next 'Creamos mensaje formateado Mensaje = ErrString & _ vbcrlf & "Source: " & ErrSource & _ vbcrlf & "Number: " & Hex(ErrNumber) 'Grabamos el error en el "Visor de eventos" App.LogEvent Mensaje, vblogeventtypeerror End Sub

Errores en ASP & VBScript

ASP: no tiene On Error Goto Label <%@ Language="VBScript" EnableSessionState="False" %> <script Language="VBScript" RunAt="Server"> 'Creamos e inicializamos conexión ADO Set AdoCon = Server.CreateObject("ADODB.Connection") AdoCon.Open Application("Provider=SQLOLEDB;...") 'Creamos e inicializamos comando ADO Set AdoCmd = Server.CreateObject("ADODB.Command") Set AdoCmd.ActiveConnection = AdoCon AdoCmd.CommandType = adcmdtext AdoCmd.CommandText = "SELECT * FROM..." 'Ejecutamos comando y escribimos ResultSet Set AdoRst = AdoCmd.Execute AdoRst.Save Response, adpersistxml 'Cerramos AdoCon AdoCon.Close </script>

ASP: si tiene Sub y Resume Next <%@ Language="VBScript" EnableSessionState="False" %> <script Language="VBScript" RunAt="Server"> Private Sub ExecuteSelectCommand 'Creamos e inicializamos conexión ADO Set AdoCon = Server.CreateObject("ADODB.Connection") AdoCon.Open Application("Provider=SQLOLEDB;Initial Catalog=...") 'Creamos e inicializamos comando ADO Set AdoCmd = Server.CreateObject("ADODB.Command") Set AdoCmd.ActiveConnection = AdoCon AdoCmd.CommandType = adcmdtext AdoCmd.CommandText = "SELECT * FROM..." 'Ejecutamos comando y escribimos ResultSet Set AdoRst = AdoCmd.Execute AdoRst.Save Response, adpersistxml 'Cerramos AdoCon AdoCon.Close End Sub On Error Resume Next ExecuteSelectCommand If (Err.Number <> 0) Then 'Escribimos mensaje de error a Response End If </script>

Errores en Oracle PL/SQL

PL/SQL: raise_application_error (1) CREATE OR REPLACE PROCEDURE BUSCAR_RUT(RUT$ IN VARCHAR2) AS NOMBRE$ CLIENTE.NOMBRE%TYPE; BEGIN... BEGIN SELECT NOMBRE INTO NOMBRE$ FROM CLIENTE WHERE RUT = RUT$; EXCEPTION WHEN NO_DATA_FOUND THEN RAISE_APPLICATION_ERROR(-20001, 'Cliente no existe'); END;... END;

PL/SQL: raise_application_error (2) Forma de llamado: raise_application_error(error, texto [, flag]); -20000 error -20999 Largo máximo de texto es 2048 bytes Si flag es FALSE (default) se reemplaza todos los errores anteriores, de lo contrario se acumula a los anteriores

PL/SQL: Transacción autónoma (1) CREATE OR REPLACE PROCEDURE EJEMPLO(...) AS BEGIN...... Instrucciones que pueden generar una excepción... COMMIT; EXCEPTION WHEN OTHER THEN INSERT INTO ERRORES...; -- Totalmente inútil END; ROLLBACK;

PL/SQL: Transacción autónoma (2) CREATE OR REPLACE PROCEDURE LOG_ERROR(MENSAJE$ IN VARCHAR2) AS PRAGMA AUTONOMOUS_TRANSACTION; BEGIN INSERT INTO ERRORES (ID, FECHA_HORA, MENSAJE) VALUES (ERRORES_SEQ.NEXTVAL, SYSTIMESTAMP, MENSAJE$); COMMIT; -- Commit autónomo END;

PL/SQL: Transacción autónoma (3) CREATE OR REPLACE PROCEDURE EJEMPLO(...) AS BEGIN...... Instrucciones que pueden generar una excepción... COMMIT; EXCEPTION WHEN OTHER THEN LOG_ERROR(SQLERRM); -- Ahora funciona END; ROLLBACK;

Comentarios finales Siempre libere los recursos con finally Nunca se trague (pierda) la información de una excepción: mensaje, stack, causa Redispare excepciones con valor agregado, incluyendo la excepción original (causa) Haga logging de una excepción sólo una vez, en el método que inició el trabajo

Muchas gracias