String Template for errors - c#

I dont know if I am expressing the proper terminology here, so please correct me and I will update the thread properly.
I have a lot of error options and I would like a Template so I dont have to either retype the error string over and over, nor have a bunch of string + string ... in my code. Here is what I mean:
if( reasonFailed == ReasonFailed.BAD_INPUT )
MessageBox.Show("Error: Failed because: Bad User Input. Please try again");
else if( reasonFailed == ReasonFailed.SERVER_RESPONSE_FAILED )
MessageBox.Show("Error: Failed because: Server failed to respond. Please try again");
else if( reasonFailed == ReasonFailed.INTERNAL_ERROR )
MessageBox.Show("Error: Failed because: Internal Error. Please try again");
...
I know I can put:
string beginningError = "Error: Failed because: ";
string endError = " Please try again";
MessageBox.Show(beginningError + "error..." + endError);
but I was hoping for something more elegant, like:
string errorTemplate = "Error: Failed because: {0}. Please try again";
MessageBox.Show(errorTemplate, "error...");
Anything available like this?

Use String.Format to format your error:
MessageBox.Show(String.Format(errorTemplate, "error..."));

Have you tried using the String.Format function ?
It is documented here :
http://msdn.microsoft.com/en-us/library/system.string.format.aspx

Related

How can I get a message if a string does not exist?

I'm attempting to read a text file and delete a user entered string. I cannot get it to report a message if the string does not exist.
I cannot explain everything I've tried to this point, it's been many things. I know there is nothing in it's current form that would give me the results I expect, but I've tried many many things and this is currently where it's at. For the code that is there, it's doing everything I'm telling it to do.
if (rButtonDelete.Checked)
{
bool isValid = txtID.Text.Length < 5;
if (txtID.Text == "")
{
lbOne.Items.Add("You must enter a fixture to delete.");
}
else
if(!isValid==false)
{
lbOne.Items.Add("Enter full fixture ID to delete.");
}
else
{
var oldLines = System.IO.File.ReadAllLines(#"F:\09 Quality\CMM Fixtures\fixtures.txt");
var newLines = oldLines.Where(lines => !lines.Contains(txtID.Text));
System.IO.File.WriteAllLines(#"F:\09 Quality\CMM Fixtures\fixtures.txt", newLines);
lbOne.Items.Add(txtID.Text + " was deleted.");
}
}
As stated above, as it exists now, it does everything I am telling it to do. I just need to report that a string being searched for does not exist if in doesn't. No matter what I type into the text box, it tells me it's been deleted, even if it doesn't exist.
How about this:
if (oldLines.Count() == newLines.Count())
{
lbOne.Items.Add(txtID.Text + " does not exist.");
}
else
{
lbOne.Items.Add(txtID.Text + " was deleted.");
}

Catch System.ArgumentException The URL cannot be empty

I'm trying to the catch System.ArgumentException "The URL cannot be empty." and display a message:
catch (System.ArgumentException errormsg)
{
string errorVar = Convert.ToString(errormsg);
if (errorVar == "System.ArgumentException: The URL cannot be empty.")
{
MessageBox.Show("The URL / Filename cannot be empty. Please check and try again");
}
else
{
MessageBox.Show("There is no message for this error:- " + errorVar);
}
}
At the moment, it keeps running the "Else" scenario with the message box of :
NB: line 153 = doc.Load(openFileDialog1.FileName);
Could someone please help me get it running the "if" instead of the "else" ?
Instead of trying to parse the exception, you should be looking at what causes it. In this case, the problem is that openFileDialog1.FileName is empty, so, what you should be doing is something like this:
try
{
if (string.IsNullOrEmpty(openFileDialog1.FileName))
{
MessageBox.Show("You need to select the file to open");
}
else
{
// Only attempt to do this if you know the user selected some value
doc.Load(openFileDialog1.FileName);
}
}
catch (ArgumentException ex)
{
//Show some error that is not caused by the URL being empty
}
As a general rule, you need to validate user input before attempting to use it.
string errorVar = errormsg.Message; //this would give you the error message
then you can compare it
if (errorVar.Equals("The URL cannot be empty."))
you can also use .Contains or .StartsWith

String FormatException

I'm doing an activity that asks your name, and if a number is inserted it should tell that the input is invalid.
Here's my code:
try {
Console.Write("Enter your first name: ");
string fname = Console.ReadLine();
Console.Write("You're Name is: " + fname);
}
catch (Exception) {
Console.Write("INVALID NAME");
}
Sample output:
Enter you're first name: 123hjay
INVALID NAME!!
I know my exception is wrong; I need your help guys.
You seem to have misunderstood the purpose of exceptions.
Exceptions are thrown when a program encounters an error in its execution. For example assigning a letter to an int would throw an error. While opinions vary, I tend not to handle user input errors with exceptions. Furthermore, think about the logic you wrote in your code. How could the program know that entering numbers into a variable named fname is incorrect?
Write in logic into your program to test for input errors and then return an appropriate response. In your case, if you wanted to ensure that there were no numbers entered, you could do the following:
if (name.Any(char.IsNumber))
{
Console.WriteLine("Invalid Name.");
}
Console.ReadLine();
As my comment says (in the question), I didn't really get what it is you are asking, because it doesn't throw anything, but if you did want it to throw an error (also suggested by the comments), this should help:
Console.Write("Enter you're first name: ");
string fname = Console.ReadLine();
foreach (var character in fname)
{
if (Char.IsDigit(character))
throw new Exception("Numbers are not allowed.");
}
Console.Write("You're Name is: " + fname);
It's very straight forward and you can read it as English and understand what I've done.
You can mess around with the code, look at similar functions with Visual Studios IntelliSense and tweak it to your needs.
If you need, add a try & catch blocks, of course.
for the courtesy of replying back, here is the answer.
Hint: your exception is right!
Enter in your console "Glee" it will not throw exception.
If you type "7337" it does throw exception.
try to use : fname.ToString();

"Talk / Say" functionality in a game

So I've been racking my brain trying to figure out how to implement a "talk" function in my game. I'm new to C# programming but I've been doing as much reading and experimenting as I can with the language.
This is what I have so far:
Comm comm = new Comm();
string message = null;
if (InputBox.Text == "say " + message)
{
OutputBox.AppendText(comm.do_say(message));
}
class Comm
{
public string do_say(string message)
{
return "You say: " + message + "\n";
}
}
Now, this doesn't work. I think I know why, but I can't seem to figure out just how to redo it so it does work... I've tried to replace:
(InputBox.Text == "say " + message)
with
(InputBox.Text == "say {0}", message)
and it doesn't work either. So, now I'm out of ideas on how to make this work. I tried searching stackoverflow and google for answers but came up with nothing.
Any help or hints on how to fix it would be great!
Thanks.
You don't know what the message is in advance, right? You need to search for the "Say ", and take the rest of the string as input.
if(InputBox.Text.StartsWith("Say "))
OutputBox.Text += InputBox.Text.SubString(4);
SubString(4) will return whatever's after the first 4 characters in the string, everything after the "Say "
You seem to be looking for pattern matching here, but C# doesn't support pattern matching. In other words, simply writing
if (InputBox.Text == "say " + message)
does not automatically assign "foo" to message whenever the user types "say foo".
Instead, you should probably use regular expressions, which are implemented in C# with the Regex class. Try something like
Match m = Regex.Match(InputBox.Text, #"^say\s+(.*)$", RegexOptions.IgnoreCase);
if (m.Success)
{
OutputBox.AppendText(Comm.GetScreenoutput(m.Groups[1].Value));
}
You don't need to make do_say an instance method, so in the code above I have assumed that Comm is transformed to
static class Comm
{
public static string GetScreenOutput(string message)
{
return "You say: " + message + "\n";
}
}
This code follows the naming conventions for C# code, using Pascal case for method names.
if (InputBox.Text.ToUpper().StartsWith("SAY "))
{
OutputBox.AppendText(comm.do_say(message));
}
This will check if the user used the word say, regardless of the case used.

When to use try/catch blocks?

I've done my reading and understand what a Try/Catch block does and why it's important to use one. But I'm stuck on knowing when/where to use them. Any advice? I'll post a sample of my code below in hopes that someone has some time to make some recommendations for my example.
public AMPFileEntity(string filename)
{
transferFileList tfl = new transferFileList();
_AMPFlag = tfl.isAMPFile(filename);
_requiresPGP = tfl.pgpRequired(filename);
_filename = filename.ToUpper();
_fullSourcePathAndFilename = ConfigurationSettings.AppSettings.Get("sourcePath") + _filename;
_fullDestinationPathAndFilename = ConfigurationSettings.AppSettings.Get("FTPStagePath") + _filename;
_hasBeenPGPdPathAndFilename = ConfigurationSettings.AppSettings.Get("originalsWhichHaveBeenPGPdPath");
}
public int processFile()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine(" ");
sb.AppendLine(" --------------------------------");
sb.AppendLine(" Filename: " + _filename);
sb.AppendLine(" AMPFlag: " + _AMPFlag);
sb.AppendLine(" Requires PGP: " + _requiresPGP);
sb.AppendLine(" --------------------------------");
sb.AppendLine(" ");
string str = sb.ToString();
UtilityLogger.LogToFile(str);
if (_AMPFlag)
{
if (_requiresPGP == true)
{
encryptFile();
}
else
{
UtilityLogger.LogToFile("This file does not require encryption. Moving file to FTPStage directory.");
if (File.Exists(_fullDestinationPathAndFilename))
{
UtilityLogger.LogToFile(_fullDestinationPathAndFilename + " alreadyexists. Archiving that file.");
if (File.Exists(_fullDestinationPathAndFilename + "_archive"))
{
UtilityLogger.LogToFile(_fullDestinationPathAndFilename + "_archive already exists. Overwriting it.");
File.Delete(_fullDestinationPathAndFilename + "_archive");
}
File.Move(_fullDestinationPathAndFilename, _fullDestinationPathAndFilename + "_archive");
}
File.Move(_fullSourcePathAndFilename, _fullDestinationPathAndFilename);
}
}
else
{
UtilityLogger.LogToFile("This file is not an AMP transfer file. Skipping this file.");
}
return (0);
}
private int encryptFile()
{
UtilityLogger.LogToFile("This file requires encryption. Starting encryption process.");
// first check for an existing PGPd file in the destination dir. if exists, archive it - otherwise this one won't save. it doesn't overwrite.
string pgpdFilename = _fullDestinationPathAndFilename + ".PGP";
if(File.Exists(pgpdFilename))
{
UtilityLogger.LogToFile(pgpdFilename + " already exists in the FTPStage directory. Archiving that file." );
if(File.Exists(pgpdFilename + "_archive"))
{
UtilityLogger.LogToFile(pgpdFilename + "_archive already exists. Overwriting it.");
File.Delete(pgpdFilename + "_archive");
}
File.Move(pgpdFilename, pgpdFilename + "_archive");
}
Process pProc = new Process();
pProc.StartInfo.FileName = "pgp.exe";
string strParams = #"--encrypt " + _fullSourcePathAndFilename + " --recipient infinata --output " + _fullDestinationPathAndFilename + ".PGP";
UtilityLogger.LogToFile("Encrypting file. Params: " + strParams);
pProc.StartInfo.Arguments = strParams;
pProc.StartInfo.UseShellExecute = false;
pProc.StartInfo.RedirectStandardOutput = true;
pProc.Start();
pProc.WaitForExit();
//now that it's been PGPd, save the orig in 'hasBeenPGPd' dir
UtilityLogger.LogToFile("PGP encryption complete. Moving original unencrypted file to " + _hasBeenPGPdPathAndFilename);
if(File.Exists(_hasBeenPGPdPathAndFilename + _filename + "original_which_has_been_pgpd"))
{
UtilityLogger.LogToFile(_hasBeenPGPdPathAndFilename + _filename + "original_which_has_been_pgpd already exists. Overwriting it.");
File.Delete(_hasBeenPGPdPathAndFilename + _filename + "original_which_has_been_pgpd");
}
File.Move(_fullSourcePathAndFilename, _hasBeenPGPdPathAndFilename + _filename + "original_which_has_been_pgpd");
return (0);
}
}
}
The basic rule of thumb for catching exceptions is to catch exceptions if and only if you have a meaningful way of handling them.
Don't catch an exception if you're only going to log the exception and throw it up the stack. It serves no meaning and clutters code.
Do catch an exception when you are expecting a failure in a specific part of your code, and if you have a fallback for it.
Of course you always have the case of checked exceptions which require you to use try/catch blocks, in which case you have no other choice. Even with a checked exception, make sure you log properly and handle as cleanly as possible.
Like some others have said, you want to use try-catch blocks around code that can throw an Exception AND code that you are prepared to deal with.
Regarding your particular examples, File.Delete can throw a number of exceptions, for example, IOException, UnauthorizedAccessException. What would you want your application to do in those situations? If you try to delete the file but someone somewhere else is using it, you will get an IOException.
try
{
File.Delete(pgpdFilename + "_archive")
}
catch(IOException)
{
UtilityLogger.LogToFile("File is in use, could not overwrite.");
//do something else meaningful to your application
//perhaps save it under a different name or something
}
Also, keep in mind that if this does fail, then the File.Move you do outside of your if block next will also fail (again to an IOException - since the file was not deleted it is still there which will cause the move to fail).
I was taught to use try/catch/finally for any methods/classes where multiple errors could occur and that you can actually handle. Database transactions, FileSystem I/O, streaming, etc. Core logic usually doesn't require try/catch/finally.
The great part about try/catch/finally is that you can have multiple catches so that you can create a series of exception handlers to deal with very specific error or use a general exception to catch whatever errors you don't see coming.
In your case, you're using File.Exists which is good, but their maybe another problem with the disk that may throw another error that File.Exists cannot handle. Yes, it's a boolean method, but say the File is locked and what happens if you try to write to it? With the catch, you can plan for a rare scenario, but without try/catch/finally, you may be exposing the code to completely unforeseen conditions.
The other guys have given quite a number of good pointers and references.
My input is a short one:
When to use it is one thing, equally or more importanly is how to use it properly.
PS: "it" is refeings to "trying-catching exceptions".

Categories

Resources