Sometimes I'm getting an exception when trying to get the position of the BackgroundAudioPlayer.Instance. It's happening very rarely, but I've been able to get a StackTrace. The strange thing is, this code is executed every second while playing a track. What could be the cause of this error?
I'm getting this StackTrace.
System.SystemException: HRESULT = 0xC00D36C4 ---> System.Runtime.InteropServices.COMException: Exception from HRESULT: 0xC00D36C4 at
Microsoft.Phone.BackgroundAudio.Interop.IAudioPlaybackManager.get_CurrentPosition() at
Microsoft.Phone.BackgroundAudio.BackgroundAudioPlayer.get_Position() --- End of inner exception stack trace --- at
Microsoft.Phone.BackgroundAudio.BackgroundAudioPlayer.get_Position() at
MC.PodCast.Common.ViewModel.PlayerViewModel.UpdateTrackPosition() at
MC.PodCast.Common.ViewModel.PlayerViewModel.ReactToBackgroundAudioPlayer() at
MC.PodCast.Common.ViewModel.PlayerViewModel.Initialize() at
MC.PodCast.Common.ViewModel.PlayerViewModel.<<get_InitializeCommand>b__5>d__6.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__0(Object state)
Of course the code I'm using is just plain simple.
public void UpdateTrackPosition()
{
if (_backgroundAudioPlayer != null && _backgroundAudioPlayer.Track != null)
{
Position = _backgroundAudioPlayer.Position;
}
else
{
Position = null;
}
}
That code is linked to MF_MEDIA_ENGINE_ERR_SRC_NOT_SUPPORTED but I'm guessing that you do have sound.
I have found that the BackgroundAudioPlyer can be very weird. I wrap most of my calls with a "Safe" extension method.
Example
public static PlayState PlayerStateSafe(this BackgroundAudioPlayer source)
{
PlayState state;
try
{
state = source.PlayerState;
}
catch (InvalidOperationException)
{
state = PlayState.Unknown;
}
return state;
}
Related
My question is: I am trying to skip some stackframes that come from library code. If I want to test this, how do I best/easiest force a situation where the stacktrace has one or more frames on top that come from library code?
Details:
My goal with the code below is to be able to log the origin of an exception in my source code. However, in some cases the exception is triggered in library code, so I get a stacktrace that looks like this:
System.Net.WebException: The operation has timed out
at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)
at System.Net.HttpWebRequest.GetRequestStream()
at Microsoft.Bing.Platform.ConversationalUnderstanding.ObjectStore.ObjectStoreClientHelperClass.d__7``2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.Bing.Platform.ConversationalUnderstanding.ObjectStore.ObjectStoreCoprocRequest.d__10`4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
So basically I want to move on down the stackframes until I hit a spot where I have actual useful information, skipping the library methods that don't really tell me anything useful.
Here's the code I want to test:
public static (string Path, string Method, int Line) TryGetExceptionOrigin(this Exception e, string defaultPath, string defaultMethod, int defaultLine)
{
var defaultRes = (Path: defaultPath, Method: defaultMethod, Line: defaultLine);
var st = new StackTrace(e.GetInnerMostException(), true);
if (st.FrameCount == 0)
{
return defaultRes;
}
// Walk down the stack, ignoring framework code etc. with no useful information. We need a file name to be happy
for (int i = 0; i < st.FrameCount; i++)
{
var bottomFrame = st.GetFrame(i);
if (!(string.IsNullOrEmpty(bottomFrame.GetFileName())))
{
return (
Path: bottomFrame.GetFileName() ?? string.Empty, // Is null if no debug information
Method: bottomFrame.GetMethod().Name, // Documentation does not say this can ever be null
Line: bottomFrame.GetFileLineNumber()); // Is 0 if no debug information
}
}
// OK no match, we return the default information
return defaultRes;
}
Some unnecessarily convoluted stuff like this should do nicely:
try
{
Func<int> d = () =>
{
try
{
return Guid.Parse("*").ToByteArray()[0];
}
catch (Exception)
{
throw;
}
};
Action a = () => { String.Format("{0}", 1 / d()); };
a();
}
catch (Exception ex)
{
var useful = ex.TryGetExceptionOrigin(null, null, 0);
}
This example results in an exception call stack with three user code and four framework/library code entries.
Found it at https://dotnetthoughts.wordpress.com/2007/10/27/where-did-my-exception-occur/
private static void ThrowIt()
{
Divide(3M, 0M);
}
static decimal Divide(decimal a, decimal b)
{
return (a / b);
}
This will produce this stacktrace:
st {
at System.Decimal.FCallDivide(Decimal& d1, Decimal& d2)
at System.Decimal.op_Division(Decimal d1, Decimal d2)
at ExceptionLogging.Program.Divide(Decimal a, Decimal b) in C:\Users\anjohans\source\repos\ExceptionLogging\ExceptionLogging\Program.cs:line
98 at ExceptionLogging.Program.ThrowIt() in
C:\Users\anjohans\source\repos\ExceptionLogging\ExceptionLogging\Program.cs:line
93 at ExceptionLogging.Program.ThrowLater() in
C:\Users\anjohans\source\repos\ExceptionLogging\ExceptionLogging\Program.cs:line
88 at ExceptionLogging.Program.Main(String[] args) in
C:\Users\anjohans\source\repos\ExceptionLogging\ExceptionLogging\Program.cs:line
17 } System.Diagnostics.StackTrace
I have been playing around with Exceptions to learn more about how I should use them properly. So far, I know that throw keeps the original stack trace; throw new CustomException(...) is generally used when wanting to add more information about the exception that took place or add/change the message, or even change the type of Exception itself; and throw ex should never ever be used, unless I want to lose the original stack trace.
So I wrote a small program where I could catch and rethrow an exception several times while adding something to the original message.
public class Sample
{
static void Main(string[] args)
{
new Tester().FirstCall();
}
}
public class Tester
{
public void FirstCall()
{
try
{
SecondCall();
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
Console.WriteLine(e.Message);
}
}
public void SecondCall()
{
try
{
ThirdCall();
}
catch (GoodException ex)
{
throw new Exception(ex.Message, ex);
}
}
public void ThirdCall()
{
try
{
FourthCall();
}
catch (ArithmeticException ae)
{
throw new GoodException("Arithmetic mistake: " + ae.Message, ae);
}
}
public void FourthCall()
{
int d = 0;
int x = 10 / d;
}
}
Where GoodException is a custom exception implemented correctly.
I'm expecting the console to display something like this:
at PlayingWithExceptions.Tester.FourthCall() in d:\Projects\PlayingWithExceptions\PlayingWithExceptions\Trying.cs:line 67
at PlayingWithExceptions.Tester.ThirdCall() in d:\Projects\PlayingWithExceptions\PlayingWithExceptions\Trying.cs:line 59
at PlayingWithExceptions.Tester.SecondCall() in d:\Projects\PlayingWithExceptions\PlayingWithExceptions\Trying.cs:line 41
at PlayingWithExceptions.Tester.FirstCall() in d:\Projects\PlayingWithExceptions\PlayingWithExceptions\Trying.cs:line 25
Arithmetic mistake: Attempted to divide by zero.
But instead I'm getting this:
at PlayingWithExceptions.Tester.SecondCall() in d:\Projects\PlayingWithExceptions\PlayingWithExceptions\Trying.cs:line 41
at PlayingWithExceptions.Tester.FirstCall() in d:\Projects\PlayingWithExceptions\PlayingWithExceptions\Trying.cs:line 25
Arithmetic mistake: Attempted to divide by zero.
For some reason it only goes as far as the second call. Even though I'm passing the caught exception as an InnerException, the stack trace is still lost. I'm aware that if I just wrote throw instead of throwing a new exception, I could keep the original stack trace, but if I do that I won't be able to change the original message (which was the whole point of this exercise).
So my question is, what can I do to change the Exception message AND keep the original stack trace the whole way?
EDIT: Since an exception should not be used logic control and only caught once, the proper way to keep the original stack trace AND show the new message is to wrap the FourthCall in a try/catch (where the new Exception with its message is generated), and catch it only once all the way up in the FirstCall.
The stack trace isn't "lost" it's pushed into the InnerException, just like you told it to be. The "outer" exception in this case, did not participate in the call chain of the Inner exception - it's a brand new exception which originates in SecondCall, so that's the beginning of its stack trace.
And yes, the commenters are correct. To control your messaging, you won't do that by trying to set the message in the Exception object - Exceptions should be handled by code, messages are for users. So, you'll log the message, display it to the user, something like that.
Don't know if it still relevant for you. Just use the keyword "throw" without the exception append to it , then the trace will not be lost and the original exception will be throws. not as inner.
I have a partial-trust AppDomain within which I run a full-trust debugging window. Using PermissionSetAttribute to get permissions I can create the window and do plenty of things with it, but sometimes a SecurityException will be thrown during data binding.
One easily reproducible case throws this: Property accessor 'Namespace' on object 'System.RuntimeType' threw the following exception:'Request failed.'. Digging into the exception I can see that it was thrown when full trust was demanded.
No problem, the debug window assembly has full trust and I simply need to assert it. But when I look at the stack trace of the inner SecurityException I see this:
at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
at System.Security.CodeAccessSecurityEngine.Check(PermissionSet permSet, StackCrawlMark& stackMark)
at System.Security.PermissionSet.Demand()
at System.SecurityUtils.DemandGrantSet(Assembly assembly)
at System.SecurityUtils.DemandReflectionAccess(Type type)
at System.SecurityUtils.MethodInfoInvoke(MethodInfo method, Object target, Object[] args)
at System.ComponentModel.ReflectPropertyDescriptor.GetValue(Object component)
It ends right there, at ReflectPropertyDescriptor.GetValue.
In Visual Studio's Call Stack window I can see ReflectPropertyDescriptor.GetValue at the very tip of the stack. That stack goes all the way back to the creation of the debug window and the security assert I performed there, which is exactly what I want.
Why has the stack been split in two like this? How can I stop it from happening?
I'm using .Net 4.0 security (i.e. Level 2).
This isn't that odd. Visual studio's call stack is showing you the method which you were at when the current exception was thrown . The InnerException shows the callstack of where the inner exception exception occurred. After the inner exception was thrown, it propagated up the callstack thus unwinding it until it got to ReflectPropertyDescriptor.GetValue. At that point, it was caught in a catch block and set as the inner exception of a new exception which then thrown and bubbled all the way up. So the call stack for the second exception begins at the point it was thrown (i.e. ReflectPropertyDescriptor.GetValue)
Here's a simple example which reproduces this.
namespace Exceptions
{
class ExceptionTester
{
public void Run()
{
ThrowSecondException();
}
public void DoSomething()
{
DoMore();
}
public void DoMore()
{
ThrowFirstException();
}
public void ThrowFirstException()
{
throw new FooException();
}
public void ThrowSecondException()
{
try
{
DoSomething();
}
catch (FooException e)
{
throw new BarException("derp", e);
}
}
}
class FooException : Exception
{
}
class BarException : Exception
{
public BarException(string msg, Exception inner) : base(msg, inner)
{
}
}
class Program
{
static void Main(string[] args)
{
var tester = new ExceptionTester();
tester.Run();
}
}
}
When the second exception of type BarException is thrown, you'll notice that visual studio has ThrowSecondException at the top of the call stack because that is where BarException was thrown. However, when you dig into BarException's InnerException and look at FooException's call stack, it'll show you where FooException was thrown (ThrowFirstException()).
I do not know much about these technologies, and was not very successful at finding how an exception stack is displayed.
Therefore, several basic questions:
how are 2 independent successive exceptions shown?
how are several chained exceptions displayed?
is the root cause displayed at the top or the bottom of the stack?
It's pretty easy to try this for yourself. For example:
using System;
class Test
{
static void Main(string[] args)
{
try
{
Top();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
static void Top()
{
try
{
Middle();
}
catch (Exception e)
{
throw new Exception("Exception from top", e);
}
}
static void Middle()
{
try
{
Bottom();
}
catch (Exception e)
{
throw new Exception("Exception from middle", e);
}
}
static void Bottom()
{
throw new Exception("Exception from bottom");
}
}
Results (the first two lines would be on one line if it were long enough):
System.Exception: Exception from top ---> System.Exception: Exception from middle
---> System.Exception: Exception from bottom
at Test.Bottom() in c:\Users\Jon\Test\Test.cs:line 43
at Test.Middle() in c:\Users\Jon\Test\Test.cs:line 33
--- End of inner exception stack trace ---
at Test.Middle() in c:\Users\Jon\Test\Test.cs:line 37
at Test.Top() in c:\Users\Jon\Test\Test.cs:line 21
--- End of inner exception stack trace ---
at Test.Top() in c:\Users\Jon\Test\Test.cs:line 25
at Test.Main(String[] args) in c:\Users\Jon\Test\Test.cs:line 9
When two independent successive exceptions are thrown, the first one will interrupt the normal execution of the program, until it is handled. Then, the second exception will be thrown in the same way, if the program was not terminated by the first one.
As for chained exceptions, you will see the last thrown exception, but that last exception was thrown when handling another exception and so forth. For example:
void Foo()
{
throw new FooException("foo");
}
void Bar()
{
try
{
Foo();
}
catch(FooException ex)
{
throw new BarException("bar", /* innerException = */ ex);
}
}
So at the top of the stack you will see BarException and at the bottom, the FooException. Hope I did not miss anything.
What is the difference between
try { ... }
catch{ throw }
and
try{ ... }
catch(Exception e) {throw new Exception(e.message) }
regardless that the second shows a message.
throw; rethrows the original exception and preserves its original stack trace.
throw ex; throws the original exception but resets the stack trace, destroying all stack trace information until your catch block.
NEVER write throw ex;
throw new Exception(ex.Message); is even worse. It creates a brand new Exception instance, losing the original stack trace of the exception, as well as its type. (eg, IOException).
In addition, some exceptions hold additional information (eg, ArgumentException.ParamName).
throw new Exception(ex.Message); will destroy this information too.
In certain cases, you may want to wrap all exceptions in a custom exception object, so that you can provide additional information about what the code was doing when the exception was thrown.
To do this, define a new class that inherits Exception, add all four exception constructors, and optionally an additional constructor that takes an InnerException as well as additional information, and throw your new exception class, passing ex as the InnerException parameter. By passing the original InnerException, you preserve all of the original exception's properties, including the stack trace.
The first preserves the original stacktrace:
try { ... }
catch
{
// Do something.
throw;
}
The second allows you to change the type of the exception and/or the message and other data:
try { ... } catch (Exception e)
{
throw new BarException("Something broke!");
}
There's also a third way where you pass an inner exception:
try { ... }
catch (FooException e) {
throw new BarException("foo", e);
}
I'd recommend using:
the first if you want to do some cleanup in error situation without destroying information or adding information about the error.
the third if you want to add more information about the error.
the second if you want to hide information (from untrusted users).
One other point that I didn't see anyone make:
If you don't do anything in your catch {} block, having a try...catch is pointless. I see this all the time:
try
{
//Code here
}
catch
{
throw;
}
Or worse:
try
{
//Code here
}
catch(Exception ex)
{
throw ex;
}
Worst yet:
try
{
//Code here
}
catch(Exception ex)
{
throw new System.Exception(ex.Message);
}
Throwing a new Exception blows away the current stack trace.
throw; will retain the original stack trace and is almost always more useful. The exception to that rule is when you want to wrap the Exception in a custom Exception of your own. You should then do:
catch(Exception e)
{
throw new CustomException(customMessage, e);
}
None of the answers here show the difference, which could be helpful for folks struggling to understand the difference. Consider this sample code:
using System;
using System.Collections.Generic;
namespace ExceptionDemo
{
class Program
{
static void Main(string[] args)
{
void fail()
{
(null as string).Trim();
}
void bareThrow()
{
try
{
fail();
}
catch (Exception e)
{
throw;
}
}
void rethrow()
{
try
{
fail();
}
catch (Exception e)
{
throw e;
}
}
void innerThrow()
{
try
{
fail();
}
catch (Exception e)
{
throw new Exception("outer", e);
}
}
var cases = new Dictionary<string, Action>()
{
{ "Bare Throw:", bareThrow },
{ "Rethrow", rethrow },
{ "Inner Throw", innerThrow }
};
foreach (var c in cases)
{
Console.WriteLine(c.Key);
Console.WriteLine(new string('-', 40));
try
{
c.Value();
} catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
}
Which generates the following output:
Bare Throw:
----------------------------------------
System.NullReferenceException: Object reference not set to an instance of an object.
at ExceptionDemo.Program.<Main>g__fail|0_0() in C:\...\ExceptionDemo\Program.cs:line 12
at ExceptionDemo.Program.<>c.<Main>g__bareThrow|0_1() in C:\...\ExceptionDemo\Program.cs:line 19
at ExceptionDemo.Program.Main(String[] args) in C:\...\ExceptionDemo\Program.cs:line 64
Rethrow
----------------------------------------
System.NullReferenceException: Object reference not set to an instance of an object.
at ExceptionDemo.Program.<>c.<Main>g__rethrow|0_2() in C:\...\ExceptionDemo\Program.cs:line 35
at ExceptionDemo.Program.Main(String[] args) in C:\...\ExceptionDemo\Program.cs:line 64
Inner Throw
----------------------------------------
System.Exception: outer ---> System.NullReferenceException: Object reference not set to an instance of an object.
at ExceptionDemo.Program.<Main>g__fail|0_0() in C:\...\ExceptionDemo\Program.cs:line 12
at ExceptionDemo.Program.<>c.<Main>g__innerThrow|0_3() in C:\...\ExceptionDemo\Program.cs:line 43
--- End of inner exception stack trace ---
at ExceptionDemo.Program.<>c.<Main>g__innerThrow|0_3() in C:\...\ExceptionDemo\Program.cs:line 47
at ExceptionDemo.Program.Main(String[] args) in C:\...\ExceptionDemo\Program.cs:line 64
The bare throw, as indicated in the previous answers, clearly shows both the original line of code that failed (line 12) as well as the two other points active in the call stack when the exception occurred (lines 19 and 64).
The output of the rethrow case shows why it's a problem. When the exception is rethrown like this the exception won't include the original stack information. Note that only the throw e (line 35) and outermost call stack point (line 64) are included. It would be difficult to track down the fail() method as the source of the problem if you throw exceptions this way.
The last case (innerThrow) is most elaborate and includes more information than either of the above. Since we're instantiating a new exception we get the chance to add contextual information (the "outer" message, here but we can also add to the .Data dictionary on the new exception) as well as preserving all of the information in the original exception (including help links, data dictionary, etc.).
throw rethrows the caught exception, retaining the stack trace, while throw new Exception loses some of the details of the caught exception.
You would normally use throw by itself to log an exception without fully handling it at that point.
BlackWasp has a good article sufficiently titled Throwing Exceptions in C#.
throw is for rethrowing a caught exception. This can be useful if you want to do something with the exception before passing it up the call chain.
Using throw without any arguments preserves the call stack for debugging purposes.
Your second example will reset the exception's stack trace. The first most accurately preserves the origins of the exception.
Also you've unwrapped the original type which is key in knowing what actually went wrong... If the second is required for functionality - e.g., to add extended information or rewrap with a special type such as a custom 'HandleableException' then just be sure that the InnerException property is set too!
Throw;: Rethrow the original exception and keep the exception type.
Throw new exception();: Rethrow the original exception type and reset the exception stack trace
Throw ex;: Reset the exception stack trace and reset the exception type
If you want you can throw a new Exception, with the original one set as an inner exception.
Most important difference is that the second expression erases the type of the exception. And the exception type plays a vital role in catching exceptions:
public void MyMethod ()
{
// both can throw IOException
try { foo(); } catch { throw; }
try { bar(); } catch(E) {throw new Exception(E.message); }
}
(...)
try {
MyMethod ();
} catch (IOException ex) {
Console.WriteLine ("Error with I/O"); // [1]
} catch (Exception ex) {
Console.WriteLine ("Other error"); // [2]
}
If foo() throws an IOException, the [1] catch block will catch the exception. But when bar() throws IOException, it will be converted to plain Exception and won't be caught by the [1] catch block.
throw or throw ex, both are used to throw or rethrow the exception, when you just simply log the error information and don't want to send any information back to the caller you simply log the error in catch and leave.
But in case you want to send some meaningful information about the exception to the caller you use throw or throw ex. Now the difference between throw and throw ex is that throw preserves the stack trace and other information, but throw ex creates a new exception object and hence the original stack trace is lost.
So when should we use throw and throw e? There are still a few situations in which you might want to rethrow an exception like to reset the call stack information.
For example, if the method is in a library and you want to hide the details of the library from the calling code, you don’t necessarily want the call stack to include information about private methods within the library. In that case, you could catch exceptions in the library’s public methods and then rethrow them so that the call stack begins at those public methods.