I have methods to read various sensors and process data. Within these methods I have other methods that send commands to a circuit via serial port (to get the sensor values). A communication error may occur and I was wondering if it is ever OK to "return" an exception? For example:
public double AverageSensorValues()
{
try
{
...
double sensor1Value = SensorValue(1);
double sensor2Value = SensorValue(2);
...
}
catch (Exception ex)
{
MessageBox.Show("Error in AverageSensorValues()");
}
}
public double SensorValue(int sensorNum)
{
try {
// Send command to circuit to return value.
string response = SendCommand(commandStringToGetValue);
// Check to see if response is an error
bool isError = ErrorReturned(response);
if(isError)
ProcessError(response); // Throws exception.
... // Other things that could cause exceptions to be thrown.
}
catch (Exception ex)
{
throw new Exception("Error in SensorValue()", ex);
}
}
public void ProcessError(string errorResponse)
{
// Split string and get error parameters (#, input command, etc.)
throw new Exception(String.Format("Error-{0}: See ...", errorNumber)); // Is this OK? More readable than "ER,84,DM,3L" for example.
}
Is this ever OK or is it considered "bad practice"?
Thanks!
EDIT
I read over the various responses and it looks like I am doing this completely wrong. I attempted to use the above as a quick example but it looks like I should have just posted the full details from the get-go. So here is a more detailed example of my situation:
public double[] GetHeightAtCoords(CoordClass[] coords) // Get height measurement at various positions. Called after button click, results are displayed on UI.
{
try // Error could occur within one of these methods. If it does, not Program critical but it should notify user and not return any result.
{
for(int coordIndex = 0; coordIndex < coords.Length; coordIndex++) // Cycle through each desired position.
{
...
currentCoords = GetCurrentCoords(); // Get current actuator position.
... //Update UI.
MoveToCoords(coords[coordIndex]); // Move actuator to position.
currentCoords = GetCurrentCoords(); // Verify position.
EngageBrake(); // Lock actuator in place.
double height = GetHeight(); // Read sensor data.
ReleaseBrake(); // Release brake.
...
}
}
catch (Exception ex)
{
// Display in statusbar.
statusBar1.Text = String.Format("Error in GetHeightAtCoords(): {0}", ex.Message);
}
...
return heights; // Return position heights array.
}
public CoordClass GetCurrentCoords() // Method to read positional encoder values.
{
...
try
{
double xPosition = GetXEncoderValue(); // Return x-coord value.
double yPosition = GetYEncoderValue(); // Return y-coord value.
}
catch (Exception ex)
{
throw new Exception("Error in GetCurrentCoords(): {0}", ex.Message);
}
...
return new CoordClass(xPosition, yPosition); // Return current coords.
}
public void MoveToCoords(CoordClass coord) // Method to move actuators to desired positions.
{
try
{
...
currentCoords = GetCurrentCoords(); // See where actuators are now.
... // Setup movement parameters.
MoveToX(coord.X); // Move x-axis actuator to position.
MoveToY(coord.Y); // Move y-axis actuator to position.
}
catch (Exception ex)
{
throw new Exception("Error in MoveToCoords(): {0}", ex.Message);
}
...
}
public double GetXEncoderValue() // Method to return x-coord value.
{
string getXCoordCommand = "SR,ML,01,1"; // Serial command to get x-coord.
...
string controllerResponse = SendReceive(getXCoordCommand); // Send command, get response command.
if(!ResponseOK(controllerResponse)) // If the response doesn't match the "command OK" response (i.e. SR,ML,01,1,OK)...
{
if(IsErrorResponse(controllerResponse)) // See if response is an error response (e.g. command error, status error, parameter count error, etc.)
// Some known error type occurred, cannot continue. Format error string (e.g. ER,SRML,61) to something more meaningful and report to user (e.g. Read X Value Error: Status error.).
throw new Exception("Read X Value Error-{0}: {1}", errorNumber, (ErrorEnum)errorNumber);
else
// Something else went wrong, cannot continue. Report generic error (Read X Value Error.).
throw new Exception("Read X Value Error.");
}
...
}
// GetYEncoderValue(), MoveToX(), MoveToY(), GetHeight(), EngageBrake() and ReleaseBrake() follow the same format as EngageBrake().
Here was my logic, if...
Call order: GetHeightAtCoords() -> MoveToCoords() -> GetCurrentCoords() -> GetXEncoderValue(), error with controller response.
Throw new Exception within GetXEncoder(), catch in GetCurrentCoords() and re-throw new Exception, catch in MoveToCoords() and re-throw new Exception, catch in GetHeightAtCoords() and display message in status bar (message = "Error in GetHeightAtCoords() : Error in MoveToCoords() : Error in GetCurrentCoords() : Read X Value Error-6: Status Error").
Because GetXEncoder() can be called from multiple places within a method, I figured that if I let the original exception bubble all the way up it would be of little help to the user (e.g. "Error in GetHeightAtCoords() : Read X Value Error-6: Status Error", which time?). Take this example, which Read X Value failed? GetHeightAtCoords() -> MoveToCoords() -> GetCurrentCoords() -> GetXEncoderValue() OR GetHeightAtCoords() -> GetCurrentCoords() -> GetXEncoderValue() ?
Hopefully that is more clear :/
Is something like this ever done? How would you recommend I proceed? Thanks again Everyone for your input!