2011-10-11 26 views
6

Tengo un circuito de control con el que me comunico a través del puerto en serie. Si el comando de respuesta no coincide con un determinado formato, lo considero un error y me pregunto si debería devolver un código de error o lanzar una excepción. Por ejemplo:C# Código de error frente a la excepción

public double GetSensorValue(int sensorNumber) 
{ 
    ... 
    string circuitCommand = "GSV,01," + sensorNumber.ToString(); // Get measurement command for specified sensor. 
    string responseCommand; 
    string expectedResponseCommand = "GSV,01,1,OK"; 
    string errorResponseCommand = "ER,GSV,01,1,62"; 

    responseCommand = SendReceive(circuitCommand); // Send command to circuit and get response. 

    if(responseCommand != expectedResponseCommand) // Some type of error... 
    { 
     if(responseCommand == errorResponseCommand) // The circuit reported an error... 
     { 
     ... // How should I handle this? Return an error code (e.g. -99999) or thrown an exception? 
     } 
     else // Some unknown error occurred... 
     { 
     ... // Same question as above "if". 
     } 
    } 
    else // Everything is OK, proceed as normal. 
     ... 
} 

¡Gracias!

Respuesta

8

En casi todos casos Enviaría errores a través de excepciones. Casi nunca usaría "códigos de error" como tal, de vez en cuando es útil dar éxito/falla junto con un resultado como en int.TryParse, etc., pero no creo que esta situación funcione así. Esto suena como una verdadera condición de error que debería detener el progreso, así que una excepción es apropiada.

EDITAR: Como se señala en los comentarios, si el circuito que informa un error es realmente "esperado" y la persona que llama debería poder tratarlo y debería estar buscando activamente esa situación, entonces es razonable usar un código de estado.

Desafortunadamente gestión de errores es una de esas cosas que en realidad no hemos conseguido justo en la ingeniería de software sin embargo ...

+0

interesante; Me sorprende que recomiende excepciones para el manejo de errores estándar. ¿No reservaría excepciones por condiciones inusuales o inesperadas? –

+0

@JohnWeldon: No, los usaría para errores que significan que el código de llamada no debería continuar como si todo estuviera bien. Sin embargo, parece que * es * una condición inesperada: "Si el comando de respuesta no coincide con un determinado formato, lo considero un error". –

+0

es decirel flujo normal del programa no está destinado a manejar este caso? Estoy de acuerdo con el uso de Excepciones en ese caso. Sin embargo, si el programa normalmente espera responder a esta condición de error, no usaría excepciones. Mi interpretación de la pregunta fue la última, pero la primera sería igualmente plausible. –

2

En su caso, lanzar una excepción es mejor. Porque la persona que llama del método puede diferenciar una salida "legítima" y una condición de error. Si devuelve un código de error, sigue siendo un valor numérico, por lo que la persona que llama puede malinterpretarlo como una salida del circuito de control.

3

En sentido estricto una excepción sería utilizado cuando se está en una circunstancia 'excepcional', es decir, uno que no esperarías

Si fuera yo probablemente me devuelve un código de error en el primer caso (respuesta de error conocido), y lanzar una excepción en el segundo caso (código de error desconocido)

+0

+1 "esperar lo inesperado": al igual que tener seguro (= try + catch) no me permite conducir (= excepción de tiro) a alguien que no respeta las reglas de manejo para luego descubrir que la compañía de seguros no lo hizo lo que se necesita (manejar la excepción). – Arun

2

Personalmente, me gusta tratar con esta situación definiendo un objeto de respuesta de algún tipo. He llegado a esto a través de la experiencia haciendo esto y sopesando lo que debería considerarse excepcional. Si está interactuando con algún dispositivo y el usuario apaga el dispositivo o algo así, esta es una condición excepcional, y usted lanzaría una excepción.

Si la llamada al método particular falla o algo así, eso no es realmente excepcional, pero es un error. No quiero definir un número mágico si estoy devolviendo un doble, y no quiero lanzar una excepción. Así, defino algo como:

class DeviceResult //could also be struct 
{ 
    public double ReturnValue { get; set; } 
    public bool IsValid { get; set; } 
    public string ErrorMessage { get; set; } 
} 

Los detalles aquí no son realmente importante - se le adaptarlo a lo que los clientes quieren de su método. En este ejemplo, la API del cliente debería verificar si es válida y, de ser así, usar el valor de retorno, sin número mágico ni excepción. El paradigma es lo que es más importante. Tal como lo veo, estás usando un lenguaje orientado a objetos, por lo que también podrías usar objetos. :)

+0

Por cierto, si tiene varios tipos de devolución diferentes desde la API de su dispositivo, puede definir DeviceResult con un valor de retorno que es una "T" –

0

Código de error.

  1. Lanzar excepciones funciona más lento que devolver valores.
  2. Usted es libre de diseñar la firma del método, por lo que puede devolver el tipo que desee. Si tuviera que devolver algún tipo específico que no podría extenderse de manera significativa, entonces definitivamente debe lanzar una excepción.
  3. Es más fácil pasar por alto las excepciones que los códigos de error al invocar un método. Deberá documentar las excepciones que está lanzando su método y esperar que el otro desarrollador lo lea.
  4. La respuesta del método GetSensorValue tiene diferentes rutas. El "camino feliz" es obviamente el esperado y el más interesante. Pero si usted sabe que los consumidores pueden manejar resultados de rutas menos felices, entonces tiene sentido ir con el código de error ya que la respuesta de "ruta infeliz" es más esperada.
  5. Lanzar muchas excepciones puede hacer que su debugador se rompa constantemente en función de la configuración de excepción del depurador.
  6. La devolución de códigos de error definitivamente hará que su tipo de respuesta sea más complejo, lo que requeriría más código para desenvolver el valor. Pero, ¿es realmente difícil leer y escribir "if (response.Status == Statuses.Success) {var value = response.Value;}" en lugar de try-catch?

Cuando se trata de una buena práctica para lanzar excepciones:

  1. Cuando se puede prever que su invocación de método fallará (comprobar si se puede realizar una operación antes de realizarla). El método "perform" podría implementarse para devolver un código de error también, pero este par de métodos check-perform se considera un patrón.
  2. No se puede extender el tipo de respuesta de manera significativa, pero debe señalar una respuesta en un estado que no estaba previsto en el contrato del método.
  3. Similar a la anterior, tiene buenas razones para devolver solo el resultado de "camino feliz".
0

Yo recomendaría el uso de excepciones en la mayoría de los casos debido a algunos hechos simples:

  1. Las excepciones son globales, las # -developers C sabe lo que es una excepción (y es de esperar) cómo usarlo para la depuración .
  2. Las excepciones saltan de todos los métodos de llamada al "try catch" más cercano. Si tengo varias capas y la capa más interna arroja una excepción, entonces puedo manejar esa excepción en cualquier capa que desee (normalmente la capa más externa o la segunda más externa).
  3. La mayoría de los tipos de proyectos tienen algún tipo de método o evento sobre el que se puede sobrescribir o suscribir para implementar un código de gestión de excepción global simple. Esto hace que sea sencillo formatear mensajes de error, realizar el registro, enviar correos electrónicos y orar a los dioses (o lo que sea que hagan cuando manejan excepciones;)).

Hay algunas cosas a tener en cuenta sin embargo:

  1. no es gratis para lanzar una excepción. Si su código necesita ser 100% optimizado, lanzar excepciones puede ser algo que desee evitar.
  2. Las excepciones tienen mucha información que podría no necesitar. ¿Realmente necesita un stacktrace si todo lo que quiere hacer es mostrarle a un usuario un mensaje de error simple?

Pero como regla general, diría: se adhieren a excepciones, es muy sencillo, informativo, depurable y fácil de manejar a pesar de que podría llegar a costar un ligero rendimiento

Cuestiones relacionadas