I have a program in C# that works fine when I run it in Visual Studio.
But when I run the file I get an error in main.
The error is:
Unhandled Exception: System.IndexOutOfRangeException: Index was out of bounds of the array
My main:
The error Is at int tala = convert.toInt32...
namespace MultiplicationTable
{
class Program
{
static void Main(string[] args)
{
int tala = Convert.ToInt32(args[0]);
MultiplicationTable test = new MultiplicationTable(tala);
Console.ReadLine();
}
}
}
Any ideas?
Problem : When you run it from Visual Studio you are providing the arguments but when you run the program directly by double clicking on it you can not provide the arguments as it willbe invoked directly.
Solution : you need to provide command line arguments properly, follow the below steps to run your program from command line
Step 1: goto Command Prompt
Step 2: goto your program exe file path
Step 3: now execute the program by providing commandline arguments as below:
c:\myprogrampath\program.exe 12
Try This code to avoid Exceptions:
if(args.Length>0)
{
int tala = Convert.ToInt32(args[0]);
MultiplicationTable test = new MultiplicationTable(tala);
Console.ReadLine();
}
else
{
Console.WriteLine("No Command Line Arguments - Quiting");
}
Yes,
as the poster before said, either you have to pass arguments to your program or you have to check, if args is not null with an if-statement and "catch" this error.
if(args) {
//here your code
}
Alternatively, you could try an try - catch statement:
try {
//here you read the arguments and pass to a variable
}
catch(System.IndexOutOfRangeException) {
//other codepart
}
Related
See edits below for reproducing the behavior that I describe in this problem.
The following program will never end, because the yield return construct in C# calls the GetStrings() method indefinitely when an exception is thrown.
class Program
{
static void Main(string[] args)
{
// I expect the Exception to be thrown here, but it's not
foreach (var str in GetStrings())
{
Console.WriteLine(str);
}
}
private static IEnumerable<string> GetStrings()
{
// REPEATEDLY throws this exception
throw new Exception();
yield break;
}
}
For this trivial example, I could obviously use return Enumerable.Empty<string>(); instead, and the problem goes away. However in a more interesting example, I'd expect the exception to be thrown once, then have the method stop being called and throw the exception in the method that's "consuming" the IEnumerable.
Is there a way to produce this behavior?
EDIT: ok, the problem is different than I first thought. The program above does NOT end, and the foreach loop behaves like an infinite loop. The program below DOES end, and the exception is displayed on the console.
class Program
{
static void Main(string[] args)
{
try
{
foreach (var str in GetStrings())
{
Console.WriteLine(str);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
private static IEnumerable<string> GetStrings()
{
throw new Exception();
yield break;
}
}
Why does the try ... catch block make a difference in this case? This seems very strange to me. Thanks to #AndrewKilburn for his answer already for pointing me to this.
EDIT #2:
From a Command Prompt, the program executes the same in both cases. In Visual Studio Enterprise 2015, Update 2, whether I compile in Debug or Release, the behavior above is what I am seeing. With the try ... catch, the program ends with an exception, and without it Visual Studio never closes the program.
EDIT #3: Fixed
For me, the issue was resolved by the answer by #MartinBrown. When I uncheck Visual Studio's option under Debug > Options > Debugging > General > "Unwind the call stack on unhandled exceptions" this problem goes away. When I check the box again, then the problem comes back.
The behaviour being seen here is not a fault in the code; rather it is a side effect of the Visual Studio debugger. This can be resolved by turning off stack unwinding in Visual Studio. Try going into Visual Studio options Debugging/General and unchecking "Unwind the call stack on unhandled exceptions". Then run the code again.
What happens is that when your code hits a completely unhandled exception Visual Studio is unwinding the call stack to just before the line in your code that caused the exception. It does this so that you can edit the code and continue execution with the edited code.
The issue seen here looks like an infinite loop because when you re-start execution in the debugger the next line to run is the one that just caused an exception. Outside the debugger the call stack would be completely unwound on an unhandled exception and thus would not cause the same loop that you get in the debugger.
This stack unwinding feature can be turned off in the settings, it is enabled by default. Turning it off however will stop you being able to edit code and continue without first unwinding the stack yourself. This however is quite easy to do either from the call stack window or by simply selecting 'Enable Editing' from the Exception Assistant.
The following program will never end
That's false. The program is going to end quite quickly.
because the yield return construct in C# calls the GetStrings() method indefinitely when an exception is thrown.
This is false. It doesn't do this at all.
I'd expect the exception to be thrown once, then have the method stop being called and throw the exception in the method that's "consuming" the IEnumerable.
That's exactly what does happen.
Is there a way to produce this behavior?
Use the code you already provided.
class Program {
static void Main(string[] args) {
try {
foreach (var item in GetStrings()) {
Console.WriteLine();
}
}
catch (Exception ex) {
}
}
private static IEnumerable<string> GetStrings() {
// REPEATEDLY throws this exception
throw new Exception();
yield break;
}
}
Putting it in a try catch causes it to break out and do whatever you want
class Program
{
public static int EnumerableCount;
static void Main(string[] args)
{
EnumerableCount = 0;
try
{
foreach (var str in GetStrings())
{
Console.WriteLine(str);
Console.Read();
}
}
catch (Exception e)
{
Console.WriteLine(e);
Console.Read();
}
}
private static IEnumerable<string> GetStrings()
{
EnumerableCount++;
var errorMessage = string.Format("EnumerableCount: {0}", EnumerableCount);
throw new Exception(errorMessage);
yield break;
}
}
has the following output:
System.Exception: EnumerableCount: 1
at {insert stack trace here}
The execution flow goes into the GetStrings() method the for the first iteration, the exception is thrown and caught in the Main() method. After hitting enter, the program exits.
Removing the try catch in the Main() method causes the exception to go unhandled. The output is then:
Unhandled Exception: System.Exception: EnumerableCount: 1
at {insert stack trace here}
and the program crashes.
We're hosting the script in out app. On exceptions/crashes, we'd like to see the line number in the stacktrace.
I can't find if there is a setting to include debug info when setting up the CSScript compiler?
I believe you mean CS-Script (if not please correct me). I am not sure how you are calling it but I did find this command line documentation(it seems that the position in their help file is not reflected in their URL, you need to navigate to Overview -> Command-line interface). With .net the line number is included in the stack trace if you have a corresponding .pdb file and the line number will also be correct if there is no optimization done at compile time (this should not be a problem for CS-Script). In the documentation for cscs.exe there is a switch /dbg or /d. When you include this switch the corresponding .pdb file will be included with your .exe (or with the .dll if building a library). Once you have both files line numbers will now be available in the stack trace of any given exception that hits an operation in that assembly.
/dbg or /d
Forces compiler to include debug information.
Assume we have a file called Test.cs with some test code:
cscs.exe /e /dbg Test.cs
This will output 2 files:
Test.exe
Test.pdb
Here is the sample content of Test.cs, when you execute it you will see the line numbers.
using System;
namespace MyProgram
{
class Program
{
static void Main(string[] args)
{
try
{
throw new Exception("OH NO");
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
Console.ReadLine();
}
}
}
For Executing inline
This should also be possible with the DebugBuild flag in the EvaluatorConfig section set to true. In my example below you will get everything expected BUt when using LoadCode it uses a temporary file name so the file name looks funny although the line number is correct. There are also LoadXXX commands for loading one or more files which will give a prettier stack trace as the file name is now known.
class Program
{
static void Main(string[] args)
{
CSScript.EvaluatorConfig.DebugBuild = true;
CSScript.EvaluatorConfig.Engine = EvaluatorEngine.CodeDom;
Console.WriteLine("Debug on = " + CSScript.Evaluator.DebugBuild);
dynamic script = CSScript.Evaluator
.LoadCode(#"using System;
public class Script
{
public int Sum(int a, int b)
{
try{
throw new Exception();}
catch(Exception ex){
Console.WriteLine(ex.StackTrace);
}
return a+b;
}
}");
int result = script.Sum(1, 2);
Console.WriteLine(result);
Console.ReadLine();
}
}
I did test this all to ensure that it does work. If you have problems just let me know.
I have a function that needs to throw an exception, but I wanted it to throw that exception to the line where I called that function:
static int retrieveInt()
{
int a = getInt();
if(a == -1)
throw new Exception("Number not found"); //The runtime error is pointing to this line
return a;
}
static void Main(string[] args)
{
int a = retrieveInt(); //The runtime error would be happening here
}
After 2 hours searching I found the answer to my question. To do what I wanted it is needed to user [System.Diagnostics.DebuggerStepThrough] before the function:
[System.Diagnostics.DebuggerStepThrough]
static int retrieveInt()
{
int a = getInt();
if(a == -1)
throw new Exception("Number not found"); //The runtime error will not be here
return a;
}
static void Main(string[] args)
{
int a = retrieveInt(); //The runtime error happens now here
}
The described behaviour is not strictly possible, but working around to the desired effect is.
The issue you're running into is that in Visual Studio, execution pauses and we see exceptions from the most available location with debug info. For framework methods, this means the method call, even though the exception is being thrown a couple of calls deeper. Since the exception is coming from the same project you're debugging, you'll always have debug info for the actual throw line, and thus you'll always reach that line.
The workaround here is to utilize the Call Stack window in VS, which will include a couple lines down the method call which triggered the error, and double-clicking on this will bring you where you want to be, including all local variables at the time of the call. This is analogous to the framework exception behaviour, because if you look at the stack trace, several frames are marked as "external" because they don't have debug info.
EDIT: To add some info about the behaviour of try and catch, catch will respond to any exception not already caught - thus, even if the exception is thrown several calls deeper, if it's not handled by the time the call stack unwinds into your try block, it'll hit the appropriate catch block (if there is one).
How about this ?
public static int NewInt
{
get
{
throw new Exception("Number not found");
}
}
static void Main(string[] args)
{
int a = NewInt;
}
I am trying out NUnit, Unit Testing and Integration testing for the first time. I have been reading up and doing lots of online courses. As I'm sure you know very well it's something knowing theory and doing it in practice.
I am stuck on a particular test. The application that I have is in C# .Net 3.5.
I am trying to assert that a method with a certain bad input will throw a particular exception.
When I run the method with the same input given to the test the expected exception is thrown.
The method being tested code is:
private static bool FilePathHasInvalidChars(string userInputPath)
{
try
{
Path.GetFullPath(userInputPath);//this is where the warning appears
}
catch (Exception e)
{
Log.Error(String.Format(
"The Program failed to run due to invalid characters or empty string value for the Input Directory. Full Path : <{0}>. Error Message : {1}.",
userInputPath, e.Message), e);
return true;
}
return false;
}
I want to check that the above code can catch an exception if the provided input directory is not meeting the criteria.
The Unit test that I have at the moment is:
[Test]
public void can_throws_exception_for_empty_string()
{
var testDirectory = "";
var sut = new DirectoryInfoValidator();
Assert.Throws<ArgumentNullException>(() => sut.FilePathHasInvalidChars(testDirectory));
}
The problem I have is that the test allways fails and if I check the return it states that It expected an ArgumentNull exception but was null. I have taken a screenshot of the output from the test:
Any idea what I might be doing wrong?
EDIT: By the way I have also attempted to use
[ExpectedException(typeof(ArgumentNullException), ExceptionMessage= "Log Message", MatchType=MessageMatch.Contains)]
Have had same result with that.
On an ending note I am not sure if this is considered an Integration test or a Unit test given that my method uses Path.GetFullPath(string directory). Anyway my main issue right now is understanding what I am doing wrong. :)
Many thanks,
Jetnor.
UPDATE: After taking all the points into consideration and looking at my system's needs I have decided not to throw an exception. Instead I have decided to create tests which cover the different possible exceptions that can occur in my situation. The test method looks like this:
[Test]
public void returns_true_for_empty_string()
{
var testDirectory = "";
var sut = new DirectoryInfoValidator();
var isInvalidPath = sut.FilePathHasInvalidChars(testDirectory);
Assert.That(isInvalidPath, Is.True);
}
This is a starting point. I inted to use the [TestCase] option by providing all the inputs to one test and checking all of them at the same time. Thanks for your help guys.
Your method FilePathHasInvalidChars does not throw an exception. An exception is thrown inside of your method, but your method catches and handles the exception. Your method will always return a valid value.
If you want your method to throw an ArgumentNullException rather than logging and swallowing it, try this:
private static bool FilePathHasInvalidChars(string userInputPath)
{
try
{
Path.GetFullPath(userInputPath);//this is where the warning appears
}
catch (ArgumentNullException) {
Log.Error("The Program failed to run due to a null string value for the Input Directory.");
throw;
}
catch (Exception e)
{
Log.Error(String.Format(
"The Program failed to run due to invalid characters or empty string value for the Input Directory. Full Path : <{0}>. Error Message : {1}.",
userInputPath, e.Message), e);
return true;
}
return false;
}
With this modification, if userInputPath is null your method will log and re-throw the ArgumentNullException, and your unit test will see the exception and pass.
Your code does not throw an ArgumentNullException. Based on your code, it should never* throw any exception- it should simply return true or false.
Change your test to the NUnit equivalent of:
Assert.IsTrue(() => sut.FilePathHasInvalidChars(testDirectory));
Or, if an empty string SHOULD throw an ArgumentNullException, modify the code to something like the following**:
private static bool FilePathHasInvalidChars(string userInputPath)
{
if(string.IsNullOrWhiteSpace(userInputPath) throw new
ArgumentNullException("userInputPath");
try
{
Path.GetFullPath(userInputPath);//this is where the warning appears
}
catch (ArgumentException e)
{
Log.Error(String.Format(
"The Program failed to run due to invalid characters or empty string value for the Input Directory. Full Path : <{0}>. Error Message : {1}.",
userInputPath, e.Message), e);
throw;
}
catch (Exception e)
{
Log.Error(String.Format(
"The Program failed to run due to invalid characters or empty string value for the Input Directory. Full Path : <{0}>. Error Message : {1}.",
userInputPath, e.Message), e);
return true;
}
return false;
}
*- For a value of "never" that means "so rarely you're unlikely to have to consider it"
**- I haven't tried to compile that, so there may be errors; it's just a starting point.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Show line number in exception handling
Can someone please tell me how to get the line number of the code where the error occurred and display it to the console?
Other information like the file name or method name would be very handy.
If you want the file and line numbers, you do not need to parse the StackTrace string. You can use System.Diagnostics.StackTrace to create a stack trace from an exception, with this you can enumerate the stack frames and get the filename, line number and column that the exception was raised. Here is a quick and dirty example of how to do this. No error checking included. For this to work a PDB needs to exist with the debug symbols, this is created by default with debug build.
using System;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
try
{
TestFunction();
}
catch (Exception ex)
{
StackTrace st = new StackTrace(ex, true);
StackFrame[] frames = st.GetFrames();
// Iterate over the frames extracting the information you need
foreach (StackFrame frame in frames)
{
Console.WriteLine("{0}:{1}({2},{3})", frame.GetFileName(), frame.GetMethod().Name, frame.GetFileLineNumber(), frame.GetFileColumnNumber());
}
}
Console.ReadKey();
}
static void TestFunction()
{
throw new InvalidOperationException();
}
}
}
The output from the above code looks like this
D:\Source\NGTests\ConsoleApplication1\Program.cs:TestFunction(30,7)
D:\Source\NGTests\ConsoleApplication1\Program.cs:Main(11,9)
You can print the entire stack trace by using a try/catch around the code that can throw and then using Console.WriteLine to show the exception object:
try
{
new Program().Run();
}
catch (Exception exception) // Prefer to catch a more specific execption.
{
Console.WriteLine(exception);
}
Output:
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at Program.Run() in C:\Console Application1\Program.cs:line 37
at Program.Main(String[] args) in C:\Console Application1\Program.cs:line 45
The first line shows the type of the exception and the message. The second line shows the file, function and line number where the exception was thrown. You can also see the locations of other calls on the call stack in the following lines.
You can also get file and line numbers for uncaught exceptions. You can do this by adding a handler for the AppDomain.UncaughtException event on the current AppDomain:
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
new Program().Run();
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Console.WriteLine(e.ExceptionObject);
}
This shows a similar output to above.
Console.WriteLine(exception.StackTrace);
Make sure your application is in Debug mode or include the debug symbols (the .mdb file) in order for line numbers to appear.
You can get the stack trace by accessing Exception.StackTrace which is a string so you can print it to the console by using the Write or WriteLine methods.
You can find it in the stack trace (Exception.StackTrace property), on the last line, but only when your code has been compiled with debugging information included. Otherwise the line number will be unknown.