I am currently practicing creating my Exception class. The idea of this code is for the user to enter a password. In case its code is less than 5 characters, the program will throw an exception. I want that my program throw one exception with text("Password is too small") and the object of my Exception class use ToString method(where will write " Password Length Exception").What confuses me is why I get the message Unhandled exception.Password Length exception. Cannot print exception string because Exception.ToString () failed. You can see this in the photo
Here is my code.
public class My_Exception : Exception
{
public My_Exception(string message) : base(message)
{
Console.WriteLine(message);
}
public override string ToString()
{
throw new My_Exception(" Password Length exception ");
}
}
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("Enter your password");
string Password = Console.ReadLine();
if (Password.Length < 5)
{
throw new My_Exception(" Password is too small ");
}
}
catch(My_Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
Remove the override .ToString().
public class My_Exception : Exception
{
public My_Exception(string message) : base(message)
{
Console.WriteLine(message);
}
}
The message will be shown by the base Exception.ToString(). You shouldn't thow an exception from another exception.
And in truth, you shouldn't Console.WriteLine() from inside the constructor of an Exception. It is the try/catch block that should print in any way it wants the exception.
public class My_Exception : Exception
{
public My_Exception(string message) : base(message)
{
}
}
See running example at https://ideone.com/FchSGc
Don't throw an exception in the .ToString method. Return a string with information about what happened.
public override string ToString()
{
return " Password Length exception ";
}
Or simply create a proper exception
public class PasswordToSmallException : Exception
{
public PasswordToSmallException()
: base("Password should be at least 5 characters")
{}
}
And then you just
catch(Exception ex)
{
Console.WriteLine(ex);
}
Problem : cannot print exception string because exception.tostring() failed
Solution : I think it is a problem with the computer. I had this message also. I just restart the computer and it work.
Related
I would like to create my own custom Exception (for my own practice), I have Man class and i would like to check the name (so its not empty, null and only English chars.
I'm not sure if I'm doing this right,
1.do i need to write the code that handles with the error (if occures) in the Custom Exception class? or in the Man's setter?
2. Where should i use the "throw new Exception" for best practice?
3. any comments\improvements about my code would be welcome.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace prog
{
class Program
{
static void Main(string[] args)
{
try
{
Man p = new Man("Dan");
}
catch (Exception e)
{
throw new NameNotValidException(e.Message);
}
}
}
class Man
{
private string name;
public string Name
{
get { return name; }
set
{
if (name == "" || name == null)
{
throw new NameNotValidException("error");
}
name = value;
}
}
public Man(string name)
{
this.name = name;
}
}
class NameNotValidException : Exception
{
public NameNotValidException()
{
Console.WriteLine("Please Write a valid name!");
}
public NameNotValidException(string message)
: base(message)
{
}
public NameNotValidException(string message, Exception inner)
: base(message, inner)
{
}
}
Thanks!
In this case it is more appropriate to throw ArgumentNullException instead. Which exception you end up using (your own or ArgumentNullException) does not matter and does not change the structure of the code below OR how you should handle an Exception.
You want to check value, not name in the setter.
Handle the exception at the calling code. If the calling code is not designed to handle the Exception then do not catch that Exception OR rethrow using throw to preserve the stack trace.
Throw the exception at the location where the code fails due to... (invalid value in this case)
Be careful with your getter/setter code, you were checking the wrong values and also bypassing the setter in the constructor in which case it would never throw an Exception to begin with.
Your Man class.
public class Man {
public Man(string name)
{
// notice capital N for Name so it is set on the property, not the field
// this will execute the setter for the Name property
this.Name = name;
}
public Man(){} // optional, but do not include the parameterized constructor you had as it sets the private fields directly OR include additional validation
private string name;
public string Name
{
get { return name; }
set
{
if (string.IsNullOrEmpty(value))
throw new ArgumentNullException("Name cannot be null or empty");
name = value;
}
}
}
Calling code which handles the exception.
try
{
// use parameterized constructor
Man p = new Man("Dan");
// or use an initializer
Man p = new Man{Name = "Dan"};
// the above initializer is actually short for
Man p = new Man();
p.Name = "Dan";
}
catch (ArgumentException e)
{
Console.WriteLine("Error occurred!! Do something...");
}
If you want to create a custom exception just extend any of the exception classes, e.g.:
class MyCustomException : System.Exception
{}
and the you can do throw new MyCustomException();
When you throw an exception you're saying "Hey, something went wrong!", so the caller can then do something about that. The exception's responsibility is to say what exactly went wrong, not how to handle it. So you should remove the Console.WriteLine("Please Write a valid name!"); from the exception. Instead, put that in the code that is actually expecting that error - i.e. your Main method.
static void Main(string[] args)
{
try
{
Man p = new Man("Dan");
}
catch (NameNotValidException e)
{
Console.WriteLine("Please Write a valid name! " + e.Message);
}
Also note that I'm using NameNotValidException in the catch block, not Exception. As a general rule you should be as specific as possible in handling errors - which is why we create custom exceptions in the first place =). For example, let's say you add an Age property, which throws an AgeNotValidException. If you catch Exception e, you'll say "Please Write a valid name!" for every error, including invalid ages. By treating every exception type separately, you can handle each error differently.
About your "throw new Exception" question, you're doing it correctly: You should throw exceptions when you are unable to do something - in this case, you are unable to set the user's name because the given name is invalid. However, you should also try and be more specific with your error messages, to make errors easier to recover from: In your case, you could change it to something along the lines of throw new NameNotValidException("Name can't be empty");, so you can tell the user not only that the name is invalid, but also exactly why.
if you want to change the message only you could use this :
throw new Exception("File check failed!");
As you need to check several types of invalid input (not empty, null and only English chars), my advice is to create the custom exception with a property for invalid input type. The example is below:
class InvalidInputCustomException : Exception
{
public string InputExceptionType { get; set; }
public InvalidInputCustomException(string inputExceptionType)
{
InputExceptionType = inputExceptionType;
}
}
Then you’ll need to create your class Man in which set accessor the input (in this code keyword value) will be checked and code lines - throw new InvalidInputCustomException .. - with corresponding input exception type in this custom exception constructor will be included. This class example is below:
class Man
{
private string _name;
public Man(string name)
{
this.Name = name;
}
public string Name
{
get { return _name; }
set
{
if (value == null)
{
throw new InvalidInputCustomException("null is not valid for input.");
}
else if (value == string.Empty)
{
throw new InvalidInputCustomException("empty is not valid for input.");
}
else
{
foreach (char ch in value)
{
if (!(ch >= 'A' && ch <= 'Z') && !(ch >= 'a' && ch <= 'z') &&
!(ch >= '0' && ch <= '9'))
{
throw new InvalidInputCustomException($"non English character {ch} is " +
$"not valid for input."); ;
}
}
}
_name = value;
}
}
}
The thrown exception must be caught in the place where to initialized Man class object its property Name is attempted to set (as for example:
p.Name = inputString
or through this object constructor as in the code example below).
The example of the Console application code is below:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter name and press key Enter:");
string inputString = Console.ReadLine();
try
{
Man p = new Man(inputString);
Console.WriteLine($"Entered name - {p.Name} - is valid.");
}
catch (InvalidInputCustomException ex)
{
Console.WriteLine($"Invalid input type - {ex.InputExceptionType}. Please enter valid name.");
}
catch (Exception ex)
{
Console.WriteLine("Unhandled exception " + ex.Message);
}
Console.WriteLine("Press any key to finish the program.");
Console.ReadLine();
}
}
The code example is more for custom exceptions understanding purposes. In real applications, you need to avoid exceptions throwing in situations related to user information entering - in this case, data validation tools must be used. During custom exception creation in a real application must be provided at least a parameterless constructor and a best practice is to add three additional constructors: with a string, with a string and an exception, for serialization.
try
{
}
catch (Exception objEx)
{
clsLog.blnLogError(this.GetType().Name, MethodBase.GetCurrentMethod().Name, String.Format("Error In {0}...", MethodBase.GetCurrentMethod().Name), objEx.Message);
}
This is my Code and I need something like.
catch (MyException objEx)
{
}
class MyException
{
method()
{
//method overload with necessary parameters.
clsLog.blnLogError(this.GetType().Name, MethodBase.GetCurrentMethod().Name, String.Format("Error In {0}...", MethodBase.GetCurrentMethod().Name), objEx.Message);
}
}
In that exception class I need to get the curent class name and method name instead of writing every time.
How to achieve this?
UPDATE
[Serializable]
public class MyException : Exception
{
public MyException(string message, Exception innerException, object obj)
: base(message, innerException)
{
}
}
try
{
int f = int.Parse("d");
}
catch (MyException objEx)
{
}
It is not catching the exception and I need the method name, class name of the one where it throws error.
This cannot be done by inheriting, you will need to write an extension method so that you can call your logging method on all exception types, no matter whether they were declared by yourself or not.
To create an extension method create a static class containing a static method doing your work. Prepend the first argument of the method with the keyword this, indicating to the compiler that this method can be invoked like a member method on objects of the type of the first parameter (in your case Exception):
public static class ExceptionExtensions
{
public static void Log(this Exception ex)
{
var stackTrace = new StackTrace();
var callingMethod = stackTrace.GetFrame(1).GetMethod();
var methodName = callingMethod.Name;
var className = callingMethod.DeclaringType.Name;
clsLog.blnLogError(className, methodName, string.Format("Error In {0}...", methodName), ex.Message);
}
}
then you can call that method on every exception:
try
{
int f = int.Parse("d");
}
catch(Exception ex)
{
ex.Log();
}
For more information on extension methods see the C# Programming Guide.
I have methods that look like this:
public IDictionary<string, string> Delete(Account account)
{
try { _accountRepository.Delete(account); }
catch { _errors.Add("", "Error when deleting account"); }
return _errors;
}
public IDictionary<string, string> ValidateNoDuplicate(Account ac)
{
var accounts = GetAccounts(ac.PartitionKey);
if (accounts.Any(b => b.Title.Equals(ac.Title) &&
!b.RowKey.Equals(ac.RowKey)))
_errors.Add("Account.Title", "Duplicate");
return _errors;
}
I would like to change this method so that it returns a bool and so it throws an exception if there is an error instead of:
_errors.Add("", "Error when deleting account");
Can someone explain to me how I can throw an exception and pass a message containing a key and a value. In this case the key would be "" and the value would be "Error when deleting account".
Also in the method that calls this. How would I catch the exception?
Would it be necessary for me to make my own class and somehow throw an exception based on this class?
Create your own exception class, that can hold the data that you need:
public class AccountException : ApplicationException {
public Dictionary<string, string> Errors { get; set; };
public AccountException(Exception ex) : base(ex) {
Errors = new Dictionary<string, string>();
}
public AccountException() : this(null) {}
}
In your methods you can throw the exception. Don't return an error status also, that is handled by the exception.
Don't throw away the exception that you get in the method, include that as InnerException, so that it can be used for debugging.
public void Delete(Account account) {
try {
_accountRepository.Delete(account);
} catch(Exception ex) {
AccountException a = new AccountException(ex);
a.Errors.Add("", "Error when deleting account");
throw a;
}
}
public void ValidateNoDuplicate(Account ac) {
var accounts = GetAccounts(ac.PartitionKey);
if (accounts.Any(b => b.Title.Equals(ac.Title) &&
!b.RowKey.Equals(ac.RowKey))) {
AccountException a = new AccountException();
a.Errors.Add("Account.Title", "Duplicate");
throw a;
}
}
When calling the methods, you catch your exception type:
try {
Delete(account);
} catch(AccountException ex) {
// Handle the exception here.
// The ex.Errors property contains the string pairs.
// The ex.InnerException contains the actual exception
}
The Exception class has a Data property that is a dictionary of key/value pairs.
IDictionary<string, string> errors;
...
if (errors.Count > 0)
{
Exception ex = ... construct exception of the appropriate type
foreach(string key in _errors.Keys)
{
ex.Data.Add(key, _errors[key]);
}
throw ex;
}
Note that it's generally considered to be good practice to use Exceptions that are Serializable, so that the objects you put into the Data dictionary should also be serializable. In your example, you're just putting in strings, so you'll be fine.
Would it be necessary for me to make my own class and somehow throw an exception based on this class?
It's certainly not necessary to create your own custom Exception class, and may not be desirable. The MSDN design guidelines for Exceptions gives guidelines on choosing which Exception type to throw.
In general, you should prefer to use one of the existing Exception types unless you have an error condition that can be programatically handled in a different way from existing Exception types.
Create your own Exception and then throwing it.
public class RepositoryException : Exception
{
public RepositoryException() : base()
{
}
public RepositoryException(string key, string value) : base()
{
base.Data.Add(key, value);
}
public RepositoryException(string message) : base(message)
{
}
public RepositoryException(string message, Exception innerException) : base(message, innerException)
{
}
}
public Boolean Delete(Account account)
{
try
{
_accountRepository.Delete(account);
return true;
}
catch (Exception ex)
{
throw new RepositoryException("", "Error when deleting account");
// throw new RepositoryException("Error when deleting account", ex);
// OR just
// throw new RepositoryException("Error when deleting account");
}
}
You could throw your own exceptions instead of
_errors.Add("", "Error when deleting account");
So every _errors.Add(..) will be replaced with something like
throw new MyAppException(key, value);
How to create your own exception class was explained above. So you supply your exception object with key and value.
You should know which exception type you're going to catch
try {
Delete(account);
} catch(NullPointerException ex) {
throw new MyAppException(key, value);
}
And now in your caller-methods(outer-methods) you can catch only your exceptions.
try {
_accountRepository.Delete(account);
} catch(MyAppException ex) {
//exception handle logic
}
How to throw meaningful exceptions in F# and catch them in C#?
With the following code:
F# Library:
module Test
exception TestExc of string
let throwit message : unit=
raise (TestExc("custom exception with message: " + message))
C# Client:
namespace TestExc
{
class Program
{
static void Main(string[] args)
{
try
{
Test.throwit("Hi there");
}
catch (Test.TestExc te)
{
Console.WriteLine("Caught exception with message: " + te.Message);
}
}
}
}
I get the following message:
Caught exception with message: Exception of type 'Test+TestExc' was thrown.
But I want to see Hi there as the caught exception message.
What is the F# equivalent of the following?
class CSTestExc:System.Exception
{
public CSTestExc(String message) : base(message) { }
}
Rather than creating exception using exception TestExc of string create exception as :
type MyExp (msg:string) =
inherit Exception(msg)
I am using the following system.exception derived exception in the following manner and would expect the exception thrown in SomeFunction to be caught in the catch block in SomeOtherFunction but instead I receive an unhandled exception error when the code attempts to throw the exception, any insight would be appreciated.
void SomeFunction()
{
if (someValue == false)
{
throw(new MyException("some error, falseValue,null);
}
}
void SomeOtherFunction()
{
try
{
SomeFunction();
}
catch(MyException ex)
{
}
}
public class MyException : Exception
{
public MyException (string message, Reason reason, Exception innerException)
: base(message, innerException)
{
Reason = reason;
}
public Reason Reason { get; private set; }
}
There must be other code that is contributing to this issue - here is a complete example that works:
using System;
class Example
{
static void Main()
{
SomeOtherFunction();
}
static void SomeFunction()
{
throw new MyException("some error");
}
static void SomeOtherFunction()
{
try
{
SomeFunction();
}
catch (MyException)
{
Console.WriteLine("caught the exception");
}
}
}
class MyException : Exception
{
public MyException(string message)
: base(message) { }
}
Perhaps you can use this example and work backwards to see if there is something missing from your real code? Since there were compilation issues with your examples I am assuming that you have sanitized some production code.
I see some minor syntax errors. But I think your unhandled exception error might be coming from the constructor of MyException or the way you're handling Reason in your constructor/get,set methods. It seems like you're trying to set a value to a class, but I'm still trying to migrate from c++..so idrk what im talking about.
Try fixing syntax and working with your "Reason"