MyNewName MyNewName - 2 months ago 5
C# Question

how to show a error message when custom exception was thrown

I just started right now with the topic

exceptionhandling
. I read alot of positiv stuff about it, so I thought I should do the same, because my current technique using errorcodes is really ugly...

Okay we have following scenario: A user typed his password in a
textbox
. After pressing the login button, he gets an positiv or negativ message.

MainWindow.xaml


<TextBox x:Name="txtBoxUserPassword/>
<Button x:Name="btnLogin" Click="btnLogin_Click">Login</Button>


MainWindow.xaml.cs


private void btnCT_Click(object sender, RoutedEventArgs e)
{
DataBase db = new DataBase();
db.IsPasswordCorrect(this.txtBoxUserPassword.Text);

// How can I catch here the exception from the class to
// show the error notification?
}


DataBase.cs


public class DataBase{
public void IsPasswordCorrect(string password)
{
try{
if(password != "fooBar")
{
throw new InvalidPasswordException("You entered the wrong password. Try it again.");
}
else
{
/*
...
*/
}
}
catch(InvalidPasswordException ex){
// What should I do here? I want to give the user an
// error message with the content "You entered the wrong
// password. Try it again."
}
}
}


InvalidPasswordException.cs


public class InvalidPasswordException: Exception
{
public InvalidPasswordException(string message, Exception inner)
: base(message, inner)
{
}
}


As you can see, it's the first time I using
exceptions
. Hopefully you can help me a bit. Thanks!

Edit



I have this
switch/case construct
inside my
public void btnCT_Click()
.

switch (CheckString("EnteredString"))
{
case 1:
MessageBox.Show("Error 1");
break;
case 2:
MessageBox.Show("Error 2");
break;
case 3:
MessageBox.Show("Error 3");
break;
case 0:
MessageBox.Show("Successful");
break;
}


Here is my method from another class. The classname is not important.

public int CheckString(string enteredString)
{
if(enteredString length is larger 25 chars)
return 1;
else if(enteredString contains special characters)
return 2;
else if(enteredString dosent contain any number)
return 3;
else
return 0;
}

Answer

The first thing that I have to say is that you don't need a custom exception just for this. Looking just to the method's name (IsPasswordCorrect) anyone would expect this method to return a true/false boolean value not an exception.

So you could have a simpler

public class DataBase
{
     public bool IsPasswordCorrect(string password)
     {
          if(password != "fooBar")
             return false;
          else
             return true;
     }
}

.... at the UI level ....
if(!db.IsPasswordCorrect("notA_fooBar"))
   MessageBox.Show("You entered the wrong password. Try again");
else
   ....

However, if you really need to thrown an exception (remember that this is a costly operation in terms of performances) then do not catch it in the same method where you throw it but let it bubble up to reach the calling code

 public bool IsPasswordCorrect(string password)
 {
      if(password != "fooBar")
         throw new InvalidPasswordException("You entered the wrong password. Try again");
      ....
 }

and in the calling code (at the UI level) add the try catch blocks

private void btnCT_Click(object sender, RoutedEventArgs e)
{
     try
     {

          DataBase db = new DataBase();
          db.IsPasswordCorrect(this.txtBoxUserPassword.Text);

          // If you reach this point the password is correct
          // But it is ugly and unclear to any reader....

     }
     catch(InvalidPasswordException ex)
     {
         MessageBox.Show(ex.Message);
     }

In any case exceptions should be used only for exceptional reasons. You don't use them to drive your code. In this context the best method is to return a true/false value.


When the failure reasons are complex I usually use this approach

bool ok = true;
ok = database.IsPasswordCorrect("fooBar");
if(ok) ok = database.Method1();
if(ok) ok = database.Method2();
if(ok) ok = database.Method3();

if(!ok)
   MessageBox.Show(database.LastErrorMessage);

public class Database
{
    public string LastErrorMessage { get; set; } 
    public bool Method1()
    {
        if(errorFoundForReason1)  
        {
             LastErrorMessage = "Error found for reason1";
             return false;
        }
        if(errorFoundForReason2)  
        {
             LastErrorMessage = "Error found for reason2";
             return false;
        }
        ....
        return true;
    }
}

Of course, every boolean method in the database class, when there is a reason to fail and before returning false, sets a global variable with the exact error message involved in the failure so the client code could handle easily the message when it has finished the calls.

Comments