none
Manejo de excepciones en programacion de 3 capas RRS feed

  • Pregunta

  • hola a todos, quisiera saber si me podrian ayudar a resolver en donde o como se pasa una exepcion miren les pondre el codigo

    primero es una clase abstracta

    abstract class ABBC<T> where T: class
        {
            public abstract void Altas(T entidad);
            public abstract void Bajas(T entidad);
            public abstract void Bajas(int id);
            public abstract IEnumerable<T> Buscar(T entidad);
            public abstract T Buscar(int id);
            public abstract void Cambios(T entidad);
        }

    despues es una clase que tiene la conexion a la base de datos y la ejecucion de las consultas

    public class SQL
        {
            //Variables de la clase
            private SqlConnection miConexion;
            private string cadenaConexion;
    
            //Propiedad publica
            public string query { get; set; }
    
            //Metodos
            public void Conectar()
            {
                cadenaConexion = ConfigurationManager.ConnectionStrings["MiConexion"].ConnectionString;
                miConexion = new SqlConnection(cadenaConexion);
                miConexion.Open();
            }
    
            public void Desconectar()
            {
                miConexion.Close();
            }
    
            public SqlCommand ComandoConexionAutomatica(string aConsulta)
            {
                Conectar();
                SqlCommand comando = new SqlCommand(aConsulta, miConexion);
                return comando;
            }
    
            public SqlCommand ComandoConexionManual(string aConsulta)
            {
                SqlCommand comando = new SqlCommand(aConsulta, miConexion);
                return comando;
            }

    y ya con esas dos clases formo el primero repositorio

    class CategoriaRepository : ABBC<Entities.Categoria>
        {
            private SQL sql;
    
            public CategoriaRepository()
            {
                this.sql = new SQL();
            }
    
            public override void Altas(Categoria entidad)
            {
                sql.query = @"INSERT INTO Categorias (descripcion)VALUES(@descripcion)";
                
                try
                {
                    SqlCommand sqlCommand = sql.ComandoConexionAutomatica(sql.query);
                    sqlCommand.Parameters.AddWithValue("@descripcion", entidad.descripcion);
                }
                catch
                { 
                }
            }
    
            public override void Bajas(Categoria entidad)
            {
                throw new NotImplementedException();
            }
    
            public override void Bajas(int id)
            {
                throw new NotImplementedException();
            }
    
            public override IEnumerable<Categoria> Buscar(Categoria entidad)
            {
                throw new NotImplementedException();
            }
    
            public override Categoria Buscar(int id)
            {
                throw new NotImplementedException();
            }
    
            public override void Cambios(Categoria entidad)
            {
                throw new NotImplementedException();
            }
        }

    en la clase sql, no maneje ningun try catch no se si deberia hacerlo, pero como es la clase que se encarga de la conexion y desconexion y execucion, creo que deberia llevar un try catch en cada metodo, por si no se logra la conexion, dar una salida, pero una salida que se debe enviar hasta el repositorio, a hacerlo como le hice no poner try catch hay y ponerlo hasta el repositorio, pero hay no sabria con exactitud cual fue el error por que engloba mas, y tomar en cuenta que tambien esas exepciones se pasaran a la capa de negocio y despues a la de presentacion, pero cmo se hace eso

    viernes, 26 de octubre de 2012 17:35

Respuestas

  • deberias invocar a la base

         public class TechnicalException : Exception
        {
            public TechnicalException(string mensaje):base(mensaje)
            {
            }
        }

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    • Marcado como respuesta niqel miércoles, 31 de octubre de 2012 16:01
    lunes, 29 de octubre de 2012 19:21

Todas las respuestas

  • podrias capturar el error

    http://social.msdn.microsoft.com/Forums/es/vcses/thread/7af0980a-3c20-45dc-afd4-bd859ad1b637

    y cambiarlo de tipo, o sea podrias crear cutom Exception, por ejemplo un TecnicalException y ante un error de coenction capturar el Exception y convertirlo a TecnicalException para devovler este a la capa superior

    de esta forma no controlas cualquier error sino uno que conoces y sabes como mostrarlo al usuario

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    viernes, 26 de octubre de 2012 17:43
  • bueno pss ya lei los temas, y la verdad no los entendi muy bien

    es que para alguien de mis conocimientos esos temas estan muy avanzados jejejeje

    me quedo muy claro leandro que dices que hay que crear dos tipos de exepciones las exepciones por la logica del negocio y las exepciones por conexion a la base dedatos o consultas fallidas y eso, tambien me quedo claro me quedo claro que se me modifica el mensaje,  el problema es que no se como se hace y vi los ejemplos y no lo entendi muy bien. por ejemplo esta exepcion mia

    public void Conectar()
            {
                try
                {
                    cadenaConexion = ConfigurationManager.ConnectionStrings["MiConexion"].ConnectionString;
                    try
                    {
                        miConexion = new SqlConnection(cadenaConexion);
                        miConexion.Open();
                    }
                    catch
                    {
                        throw new Exception("No se pudo realizar la conexion, ");
                    } 
                }
                catch
                {
                    throw new Exception("No se logro la conexion, No se encuentra el archivo de conexion");
                }
            }

    esta en la capa de datos y manejo dos try para identificar los errores posibles y creo una nueva exepcion con el mensaje al error, es eso correcto? ahora eso es en la capa de datos y en la de negocio que pasa, y en la de presentacion tambien que pasam y como podria divir los errores como tu dijiste
    viernes, 26 de octubre de 2012 20:53
  • porque ahces dos try..catch en el ejmeplo que poens si con uno solo alcanza

            public void Conectar()
            {
     
                    cadenaConexion = ConfigurationManager.ConnectionStrings["MiConexion"].ConnectionString;
                    try
                    {
                        miConexion = new SqlConnection(cadenaConexion);
                        miConexion.Open();
                    }
                    catch(Exception ex)
                    {
                        throw new TechnicalException("No se pudo realizar la conexion, ", ex);
                    } 
                }
    
            }

    o sea debes convertir al tipo que ti defines

    esto permitira que en la rpesentacion detectes que el error es del tipo TechnicalException y puedas hacer determianda accion, por ejemplo mostrar lago simple al usuario o lanzar el envio de mail, etc, eso lo decides segun el tipo del error

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    viernes, 26 de octubre de 2012 23:37
  • pero no me aparece tecnical exception, que using necesito
    lunes, 29 de octubre de 2012 8:10
  • El arbol para los Tipos de Excepciones se encuentra de esta forma:

    +--System.Object  

       |

       |

       +--System.Exception  

           |

           |

           +--System.SystemException  

               |

               |

               +--System.ArgumentException  

               |   |

               |   |

               |   +--System.ArgumentNullException  

               |   |

               |   |

               |   +--System.ArgumentOutOfRangeException  

               |   |

               |   |

               |   +--System.DuplicateWaitObjectException  

               |

               |

               +--System.ArithmeticException  

               |   |

               |   |

               |   +--System.DivideByZeroException  

               |   |

               |   |

               |   +--System.OverflowException  

               |   |

               |   |

               |   +--System.NotFiniteNumberException

               |

               |

               +--System.ArrayTypeMismatchException  

               |

               |

               +--System.ExecutionEngineException  

               |

               |

               +--System.FormatException  

               |

               |

               +--System.IndexOutOfRangeException  

               |

               |

               +--System.InvalidCastException  

               |

               |

               +--System.InvalidOperationException  

               |   |

               |   |

               |   +--System.ObjectDisposedException  

               |

               |

               +--System.InvalidProgramException  

               |

               |

               +--System.IO.IOException  

               |   |

               |   |

               |   +--System.IO.DirectoryNotFoundException  

               |   |

               |   |

               |   +--System.IO.EndOfStreamException  

               |   |

               |   |

               |   +--System.IO.FileLoadException  

               |   |

               |   |

               |   +--System.IO.FileNotFoundException  

               |   |

               |   |

               |   +--System.IO.PathTooLongException  

               |

               |

               +--System.NotImplementedException  

               |

               |

               +--System.NotSupportedException  

               |

               |

               +--System.NullReferenceException  

               |

               |

               +--System.OutOfMemoryException  

               |

               |

               +--System.RankException  

               |

               |

               +--System.Security.SecurityException  

               |

               |

               +--System.Security.VerificationException  

               |

               |

               +--System.StackOverflowException  

               |

               |

               +--System.Threading.SynchronizationLockException  

               |

               |

               +--System.Threading.ThreadAbortException  

               |

               |

               +--System.Threading.ThreadStateException  

               |

               |

               +--System.TypeInitializationException  

               |

               |

               +--System.UnauthorizedAccessException

    Deberias de manejar las excepciones de la conexion de esta forma :

    try {
             }

     catch (System.InvalidOperationException ex)
             {
                string str;
                str = "Codigo:" + ex.Source;
                str += "\n" "Mensaje:"+ ex.Message;
                str += "\n" "\n";
                str += "\n" "Stack Trace :" + ex.StackTrace;
                Console.WriteLine (str, "Excepcion especifica");
             }
             catch (System.Data.SqlClient.SqlException ex)
             {
                string str;
                str = "Codigo:" + ex.Source;
                str += "\n" "Mensaje:" + ex.Message;
                Console.WriteLine (str, "Excepcion de Base de datos");
             }
             catch (System.Exception ex)
             {
                string str;
                str = "Codigo:" + ex.Source;
                str += "\n""Mensaje:" + ex.Message;
                Console.WriteLine (str, "Excepcion Generica");
             }
             finally
             {
                if conn.State == ConnectionState.Open)
                {
                   Console.WriteLine ("Finaliza bloque de try catch, cerrando conexion""Finally");
                   conn.Close();
                }
             }

     Saludos.


    © Juan Manuel Rosas Salazar

    • Propuesto como respuesta SalazarJuanMa lunes, 29 de octubre de 2012 14:55
    lunes, 29 de octubre de 2012 14:54
  • ok, pero tengo dos problemas con esa forma, una no puedo regresar console.writeline, por que no es una aplicaion de consola es una dll

    lunes, 29 de octubre de 2012 15:12
  • cuando puse InvalidOperationException no funciono despues lo cambie asi

    public void Conectar()
            {
                try
                {
                    cadenaConexion = ConfigurationManager.ConnectionStrings["MiConexion"].ConnectionString;
                    miConexion = new SqlConnection(cadenaConexion);
                    miConexion.Open();
                }
                catch (Exception ex)
                {
                    throw new Exception("No se pudo realizar la conexion, ", ex);
                }
                finally
                {
                    if (miConexion.State == ConnectionState.Open)
                    {
                        miConexion.Close();
                    }
                }
            }
    

    por ejemplo en este caso no tengo el archivo app.config en los 3 proyectos, entonces marcar ese error, pero se queda en el catch no mando la exepcion a las siguientes capas para poder manejar, estas son mis siguientes capas

    public class BusinessCategoria
        {
            public void Altas(Categoria categoria)
            {
                DataAccessLayer.CategoriaRepository repositorioCategoria = new CategoriaRepository();
                repositorioCategoria.Altas(categoria);
                repositorioCategoria = null;
            }
        }

    y la capa de UI que es una de consola por ahora solo para probar

    static void Main(string[] args)
            {
                Console.WriteLine("AGREGUE UNA DESCRIPCION A CATEGORIA");
                Entities.Categoria categoria = new Categoria();
                categoria.id = null;
                categoria.descripcion = Console.ReadLine();
                BusinessCategoria businessCategoria = new BusinessCategoria();
                businessCategoria.Altas(categoria);
                Console.WriteLine("Presione Cualquier Tecla para cerrar");
            }

    lunes, 29 de octubre de 2012 16:15
  • No se si lo mio es una buena practica pero en cada capa envio el InnerException de la exepcion para eso utilizo:

    try
    {
        //Acciones a ejecutar
    }
    catch (Exception ex)
    {
        Log.WriteLog(ex.Message);
        throw ex;
    }

    lunes, 29 de octubre de 2012 17:16
  • pero no me aparece tecnical exception, que using necesito

    no es ningun using

    TechnicalException lo tienes que creas

    usando

    public class TechnicalException : Exception{

      //aqui resto del codigo

    }

    es una exception custom que crearias

    Creating Custom Exceptions in .NET

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    lunes, 29 de octubre de 2012 17:27
  • a oko leandro si ya entendi, bueno una duda sobre eso, seria como estoy programando en capas

    hasta ahorita tengo cuatro capas

    entities

    DataAccesLayer

    BusinessLayer

    UIConsole

    bueno son 3 capas y un proyecto entities, para crear esas exepciones custom creo otro proyecto Excepciones, donde crear esas dos clases

    y para poder usarlas en cualquier capa. seria eso correcto o no??

    lunes, 29 de octubre de 2012 17:44
  • para crear esas exepciones custom creo otro proyecto Excepciones, donde crear esas dos clases

    por lo general se crea un proyecto de nombre Infrastructure

    alli se definen temas transversales a las capas, como ser seguridad, errores, logueo, etc


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    lunes, 29 de octubre de 2012 18:24
  • public class TechnicalException : Exception
        {
            public TechnicalException(string mensaje)
            {
                //Y como implemento aqui el resto dle codigo
            }
        }

    lunes, 29 de octubre de 2012 19:14
  • deberias invocar a la base

         public class TechnicalException : Exception
        {
            public TechnicalException(string mensaje):base(mensaje)
            {
            }
        }

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    • Marcado como respuesta niqel miércoles, 31 de octubre de 2012 16:01
    lunes, 29 de octubre de 2012 19:21
  • si funciona leandro

    pero cuando la exepcion es nullreferenceException hay no funciona, nunca sale del cath

    otra duda pues estoy intentando crear una clase mensajes de exepciones para no tener qe estar escribiendolos a cada rato y como tengo unos 20 repositorios imaginate pner en todos los emtoddos de altas el mismo mensaje que no se pudo insertar, por eso intento crear esta clase

    pienso que debe ser una clase statica no se si sea correcto??

    y este es el codigo

    static public class ExceptionMessages
        {
            static public string error1 = "Error 1: No se encontro el archivo app.config";
            static public string error2 = "Error 2: No se logro la conexion con el servidor";
            static public string error3 = "Error 3: No se logro Insertar en la tabla";
        }

    y asi crear una variable publica para cada mensaje, por que no una lista, por que no quiero recorrer listas para encontrar los mensajes??

    por que no adquirir los datos de un archivo externo, como un log o un xml o la misma base de datos, por que presisamente debe funcionar primero que esos metodos, bueno pongo esto para que me digan si estoy bien o mal

    y una duda mas en una clase static no admite los metodos get set, yo tenia pensado solo poner el get para que la variable sea solo de lectura pero no me lo permitio, como hago que esas variables sean solo de lectura. recordando que es una clase statica

    martes, 30 de octubre de 2012 3:59