I'm following a tutorial for making a discord bot, and after following the basics for setting up a bot I keep running into this exception:
System.Reflection.TargetInvocationException has been thrown. Exception has been thrown by the target of an invocation.
This is the code I have:
using Discord.Commands;
using Discord;
using System;
namespace TestBot
{
public class MyBot
{
DiscordClient discord;
public MyBot()
{
discord = new DiscordClient(x =>
{
x.LogLevel = LogSeverity.Info;
x.LogHandler = Log;
});
discord.UsingCommands(x =>
{
x.PrefixChar = '!';
x.AllowMentionPrefix = true;
});
var commands = discord.GetService<CommandService>();
commands.CreateCommand("test")
.Do(async (e) =>
{
await e.Channel.SendMessage("response");
});
discord.ExecuteAndWait(async () =>
{
await discord.Connect("BOT_TOKEN", TokenType.Bot);
});
}
private void Log(object sender, LogMessageEventArgs e)
{
Console.WriteLine(e.Message);
}
}
}
MonoDevelop says that the exception is happening with this piece of code:
discord.ExecuteAndWait(async () =>
{
await discord.Connect("BOT_TOKEN", TokenType.Bot);
});
I don't know how to fix this, so any help would be greatly appreciated.
(As this is my first post here, any suggestions on how to improve my posts are also appreciated.)
The true cause for your exception is being hidden from you. To fix this issue you will need to view the inner exception (and if required the inner exception of that exception and so on..). This will allow you to see the root cause of the issue and allow you to workout how to fix it.
You can view the inner exception when your code breaks in debug mode;
Clicking view detail will allow you to see more information about your exception;
Once you get to the true cause of your exception I suggest you post a new question asking how to solve that specific issue (if you can't solve it yourself).
In my case, it's caused by some exception in some inner code, and the exception was throwed up through the stack, when come to the surface and show exception window, the exception message has been losed so it shows a useless message System.Reflection.TargetInvocationException has been thrown.
The solution is, open Exception Settings Window, and check all items so that it'll break when any type of Exception happens, so you can catch the exception at the most initial position that the error reason can be esaily undederstood.
My idea comes from HERE.
Related
I've been assigned a bug to investigate. It is occurring within a component in one of our integration test environments. The exception thrown and logged is fairly generic, and completely unhelpful, so I set about augmenting the module with appropriate logging to help track down the source of the problem.
Once the logging code was shipped up, the test case ran, and failed as expected, and I eagerly summoned the logs. To my surprise there were none present past a particular async method call, despite the fact that I had narrowed the problem down to somewhere within this method.
public async Task<IResult<XmlDocument>> Handle(TrustedThirdPartyRequest request)
{
// do stuff
// do more stuff
// Exception thrown after here
Logger.Info(m => m("Someflag :{0}", someFlag)); // logs successfully
try
{
if (someflagIsOn && await deriveThisThing(clientId)) //<- Exception thrown in deriveThisThing
{
Logger.Info(m => m("Am I called?")); // no! I am not!
}
}
catch (Exception e) // super unhelpful base exception handler
{
Logger.Info(m => m("Unhelpful exception log"));
}
}
And the method in some other class
private async Task<Thing> deriveThisThing(int clientId)]
{
Logger.Info(m => m("Entered deriveThisThing")); // <-- Line is not logged
var somethingInteresting = await ThingThatThrowsException(clientId); // <-- thing throws exception
Logger.Info(m => m("Entered deriveThisThing")); // <-- Line is not logged
return Thing.Whatever;
}
This is an API project and we're using log4net. Now, I've probably omitted a mass of further information, like logger config, etc, that is needed to answer this, but at the moment I'm hoping that there's an obvious answer to this without all of that. Any clues, folks?
When the HttpClient throws an exception trying to get a page it returns a HttpRequestException. This exception doesn't really have anything to categorize the error apart from the message so the only way i can see to handle errors is like so:
try
{
HttpResponseMessage response = await client.GetAsync("http://www.example.com/");
// ...
}
catch (HttpRequestException e)
{
if(e.Message == "Name or service not known")
{
HandleNotKnown();
return;
}
if(e.Message == "Some other specific message")
{
HandleOtherError();
return;
}
// ... etc
}
I don't like doing this because I feel like at some point the error text could change in an update and break my code.
Is there a better way to handle specific errors with HttpClient?
The HttpRequestException inherits from Exception and so it has the InnerException property
Gets the Exception instance that caused the current exception.
So check this Exception for more details.
I need to translate an error in an RX stream (IObservable) into an exception in the method that contains the subscription to the stream
(because of this issue https://github.com/aspnet/SignalR/pull/1331 , Whereby errors arent serialised to clients.) Once this issue is fixed I will revert to handling error properly
e.g.
I have the following method
public IObservable<StreamItem> LiveStream()
{
_mySvc.Start();
return _mySvc.ThingChanged();
}
So I have tried to subscribe to the stream and rethrow the error, but it still doesnt get transmitted to the client:
public IObservable<StreamItem> LiveStream()
{
_mySvc.Start();
_mySvc.ThingChanged().Subscribe(item => {}, OnError, () => {});
return _mySvc.ThingChanged();
}
private void OnError(Exception exception)
{
throw new Exception(exception.Message);
}
What I need is the equivelent of throwing in the LiveStream method
e.g. this error is propogated to the client
public IObservable<StreamItem> LiveStream()
{
_mySvc.Start();
throw new Exception("some error message");
return _mySvc.ThingChanged();
}
any ideas how to achieve this?
I have found this as well, especially with a "contained" reactive pipeline—that is, one with a well-defined beginning and end. In situations like those, it may suffice to simply allow underlying exceptions to bubble up to the containing scope. But as you have found, that concept is rather foreign to Rx generally: what happens in the pipeline stays in the pipeline.
The only way out of this that I have found in a contained scenario is to "slip" the error out of the stream using Catch(), and hand back an empty IObservable to allow the stream to halt naturally (otherwise, you'll hang if you're awaiting an IObservable for completion).
This will not work within your LiveStream() method, because that context/scope should have passed out of existence long before you're consuming your stream. So, this will have to happen in the context that contains the whole pipeline.
Exception error = null;
var source = LiveStream()
.Catch<WhatYoureStreaming, Exception>(ex => {error = ex; return Observable.Empty<WhatYoureStreaming>(); })
...
await source; // if this is how you're awaiting completion
// not a real exception type, use your own
if (error != null) throw new ContainingException("oops", error);
Just don't throw error there at the end, you'll lose the original stack trace.
Try this code:
public IObservable<StreamItem> LiveStream()
{
_mySvc.Start();
return
_mySvc
.ThingChanged()
.Materialize()
.Do(x =>
{
if (x.Kind == NotificationKind.OnError)
{
OnError(x.Exception);
}
})
.Dematerialize();
}
I'm not sure that this is the best way to go - throwing exceptions like this can cause you grief inside a stream where you end up with the wrong exception handlers firing. You might need to find another solution.
I'm working on a UWP project and there's something funky going on with how errors are being presented to me. I don't know if it's VS2017 or how UWP is set up.
I have a piece of code that goes online and retrieves json content, sometimes the code works and sometimes it doesn't. It works when I use Expander control from UWP Community toolkit, and fails when I want to switch to GridView. When it doesn't work, it fails on GetStringAsync method of HttpClient. The strange behavior is that the exception isn't thrown in the method where the problem occurs, the code actually redirects me back without giving an error and as soon as it gets to the property that's supposed to have a value that isn't null, I get a null exception.
This is where the problem happens:
string httpContent = "";
using (HttpClient httpClient = new HttpClient())
{
try
{
httpContent = await httpClient.GetStringAsync(uri);
}
catch (Exception e)
{
// TODO: handle errors
var x = "";
}
}
This piece of code is called from within the view model. It starts with a constructor and RefreshServerKanesWrathDataAsync is the method where json is parsed.
public CncOnlinePageViewModel()
{
cnconline = new CncOnline();
cnconline.RefreshServerKanesWrathDataAsync();
}
The second I get to GetStringAsync, the code just goes back to the constructor like nothing happened, however the method never completes, it just exits back to the constructor, and therefore fails to update observable collections with data. I then get a null exception.
I wanted to test this with VS2015, but I updated some controls that are apparently only supported withing VS2017, so I can't run the code in other versions.
I also ran into an issue with the code prior to this problem, where I tried to access files in a directory without using a token. The behavior was exactly the same, the code wasn't telling me that I didn't have access to the directory I wanted to read, it was just throwing me out of the method back into the location that made the call to read the directory. Just like with the current problem, I would then run into a null exception, which wasn't where the main problem was.
I added Template10 and UWP community toolkit to the project, if that matters.
You shouldn't call an async method from a constructor unless you're willing to provide a callback.
public CncOnlinePageViewModel()
{
cnconline = new CncOnline();
var t = cnconline.RefreshServerKanesWrathDataAsync(); // assuming returns Task<string>
t.ContinueWith(OnCompleted);
}
private void OnCompleted(Task<string> task)
{
if (task.IsFaulted)
{
// Check error
var exception = task.Exception;
}
else if (task.IsCanceled)
{
// User hit cancel?
}
else
{
// All good!
var result = task.Result;
}
}
Here's a sample where RefreshServerKanesWrathDataAsync() returns just Task (not Task<result>)
public CncOnlinePageViewModel()
{
cnconline = new CncOnline();
var t = cnconline.RefreshServerKanesWrathDataAsync(); // assuming returns Task
t.ContinueWith(OnCompleted);
}
private void OnCompleted(Task task)
{
if (task.IsFaulted)
{
// Check error
var exception = task.Exception;
}
else if (task.IsCanceled)
{
// User hit cancel?
}
else
{
// All good!
}
}
On a side note, you may also need to have Visual Studio 2017 break when any exception is thrown. In VS2017, go to Debug->Windows->Exception Settings and make sure Common Language Runtime Exceptions has a check. If it has a filled box, click the box until it turns into a checkmark.
Also..., you can tap into an event raised when any task has an unobserved exception. You can do so in the constructor of App.xaml.cs
public App()
{
TaskScheduler.UnobservedTaskException += OnUnobservedException;
}
private static void OnUnobservedException(object sender, UnobservedTaskExceptionEventArgs e)
{
// Put break point here.
var ex = e.Exception;
// This will keep your app alive, but only do it if it's safe to continue.
e.SetObserved();
}
I am developing Windows Phone 7 Silverlight Application. I want to do Application Level error handling instead of writing try...catch... in all methods. I need to extract Method Name, Class Name and Line Number where the actual error occurred. Below is the demo code. In Application_UnhandledException event, I am expecting Method = "GenerateError" and Class = "ExceptionTesting". Also, I want to get LineNumber where the actual error occurred (this is not shown in code).
Code to generate Error:
public partial class ExceptionTesting : PhoneApplicationPage
{
// Generate Error to Test Exception Handling
private void GenerateError()
{
Int16 i = Convert.ToInt16("test");
}
}
Code that Handles Application Level Exception:
// Code to execute on Unhandled Exceptions
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
StackTrace st = new StackTrace();
var query = st.GetFrames() // get the frames
.Select(frame => new
{
Method = frame.GetMethod(),
Class = frame.GetMethod().DeclaringType
});
foreach (var q in query)
{
if (q.Method.Name.Contains("GenerateError"))
{
MessageBox.Show("Class: " + q.Class + ", Method: " + q.Method);
}
}
if (System.Diagnostics.Debugger.IsAttached)
{
// An unhandled exception has occurred; break into the debugger
System.Diagnostics.Debugger.Break();
}
}
The Application_UnhandledException method is not called from your method where the exception happens, so new StrackTrace() will not be meaningful, as you have discovered.
To get the stack trace for the place where the exception occurred, use e.Exception.StackTrace.
Note that the real exception may be wrapped inside another exception, possibly several layers deep (e.Exception.InnerException).
You could also use BugSense to get this information.
Disclaimer: I am one of the cofounders