I am using Facebook C#sdk to upload photos to user profiles using a Windows Service as a background job. And I am logging exceptions in almost every place that I can think of and for the most part it works fine. But occasionally, and sometimes it is quite frequent, I get the following exception, which does not get caught by my handler, and gets logged by the Windows Event logger, and terminates my service:
Application: PhotoService.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.Exception
Stack:
at System.Net.Security._SslStream.WriteCallback(System.IAsyncResult)
at System.Net.LazyAsyncResult.Complete(IntPtr)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Net.ContextAwareResult.Complete(IntPtr)
at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)
From the looks of it, this is happening at FacebookClient.PostTaskAsync() method call, but I have no idea how to troubleshoot with the limited stacktrace information. Below is my photo posting method block:
public void PostPhotoToTimeline(string filename, byte[] photo, EventHandler<FacebookApiEventArgs> callbackCompleted)
{
var _filename = filename;
var mediaObject = new FacebookMediaObject
{
ContentType = "image/jpeg",
FileName = _filename
}.SetValue(photo);
_fb.PostCompleted += callbackCompleted;
var parameters = new Dictionary<string, object>();
parameters["file"] = mediaObject;
_fb.PostTaskAsync("/me/photos", parameters);
}
My biggest problem at the moment is, when this exception occurs, it terminates the service and I don't have service monitoring set up yet, so no way for me to find out the service has stopped. If I understand it correctly, this exception occurs in a separate thread and is not handled, thus it brings down the whole service. Is this correct? Any idea why this might be happening and where, or anyone faced this exception before? I have read about 'legacyUnhandledExceptionPolicy' to catch these unexpected exceptions. Will this prevent my service from terminating and is it good idea to use it? Sorry if I am asking too many questions in one go but these are all related and google hasn't been my friend on this so far.
Thanks for any help you can provide.
2 months gone and not a single answer, so I will post what I did to prevent this issue which might be useful to others. Still don't know the main cause for the crash but it is occasional, so using the flag "legacyUnhandledExceptionPolicy" has worked so far, with no unexpected terminations. The flag needs to be enabled in the config file:
<runtime>
<legacyUnhandledExceptionPolicy enabled="1"/>
</runtime>
Better explanation here: MSDN Reference
Related
I have this stack trace in Fabric:
My question: From the crash log, is the function 'formatMessageAuthorName' the only cause for this EXC_BREAKPOINT crash? E.g., are there other possible causes for the crash apart from the code inside this function?
Here is my formatMessageAuthorName function:
private static func formatMessageAuthorName(firstname: String, lastname: String?=nil) -> String {
// Capitalise first character of firstname
var Cap_firstname = firstname
Cap_firstname.replaceRange(Cap_firstname.startIndex...Cap_firstname.startIndex, with: String(Cap_firstname[Cap_firstname.startIndex]).capitalizedString)
guard let lastname = lastname else { return Cap_firstname }
// if has lastname & first char, capitalise too and concat with firstname.
if let firstCharLastName = lastname.characters.first {
return "\(Cap_firstname) \(String(firstCharLastName).uppercaseString)."
} else {
return firstname
}
}
My assumption
The only clue that I know that will make the function crash is when 'firstname' is an empty string, it will crash here since it accesses invalid array index:
String(Cap_firstname[Cap_firstname.startIndex])
However, I'm still skeptical about this assumption, since I'm quite sure that 'firstname' is not empty (it's retrieved from server). I even tested it by logging into some user accounts that has this crash, and using that page (MessageViewController), but I never had the crash myself and firstname is shown correctly. It also seems to not be about iOS versions as I received crash from iOS 8, 9, and 10.
I have this crash a lot (>300) after my recent app update and I have no idea why as it never happens before, the code here does not change through the update, and I can never reproduce it with the effected users.
If the culprit can only be the code in this function, and no other possibilities (like multi-threading, Realm etc.), I can turn to focus on the server issues instead, like how 'firstname' might be an empty string. But still, I can't imagine how it could happen, since I already used those user accounts and never have this crash myself.
Thanks a lot.
EXC_BREAKPOINT is always triggered by executing a trap instruction of some sort(*) and the exception gets delivered directly to the thread that executed the trap instruction. So if you are seeing a crash report that says this thread with this stack got an EXC_BREAKPOINT, that means that thread really did to something that executed a trap instruction.
You could probably see this by looking at the crash address in your binary, you will see some kind of trap instruction there. The swift standard library uses trap instructions to signal various kinds of invalid access errors, and that code probably got inlined into the function that's crashing. So this makes sense of your example above.
(*) EXC_BREAKPOINT can also be used for data watches, but that's not what's happening here, and anyway they would still be delivered to the thread that accessed the watched data...
I'm struggling with exception handling inside my Datasnap REST Service (Delphi XE3 but also tried with Delphi 10 Seattle). I have written half a dozen Windows Service over the years and I always include a TApplicationEvents component so that I can log any Application Exceptions to the Windows Event Log.
However, this behaviour is not happening with a Datasnap Service. The TApplicationEvents.OnException event never gets fired, so I assume something else is eating the exception and handling it before it gets here.
The exception is displayed in the web service method's result, which is fine because it means I can at least display something on the client side, but I'd also like to catch it before then so that I might be able to handle different exceptions server-side.
The only consistent way I have managed so far is to wrap each individual method in a try..except block, and handle the exception in each method, before re-raising the exception. However, with a Web Service of 20 methods and growing, this isn't really going to scale up.
I have also tried implementing the OnError, OnTrace and other events of the some of the Datasnap components (TDSServer, TDSHTTPService, TDSTCPServerTransport, etc.) but these never seem to get fired either.
Has anyone come across anything like this, please?
Tl;Dr: it's not implemented in a usable fashion (in 10.1 Berlin).
I came across the same problem and after reading through a lot of source, I found no practical solution.
So an exemplary (my) StackTrace would look like this:
MyClass::MyServerMethod()
/* skipping some funny unimportant RTTI/TValue handling here */
System::Rtti::TRttiMethod::Invoke
Dsreflect::TDSMethod::Invoke(TObject, TDSMethodValues)
TDSServerConnectionHandler::DbxExecute(const TDBXExecuteMessage)
TDSServerCommand::DerivedExecuteUpdate
TExecuteCallback
TDSService::Execute(const string, const TRequestCommandHandler, TExecuteCallback)
TDSService::ProcessRequest(const string, const TRequestCommandHandler, TExecuteCallback)
TDSRESTService::ProcessREST(const string, const string, const TArray<Byte>, const TRequestCommandHandler)
TDSRESTService::ProcessGETRequest(const string, TStrings, TArray<Byte>, TRequestCommandHandler)
TDSRESTServer::DoDSRESTCommand(TDSHTTPRequest, TDSHTTPResponse, string)
TDSRESTServer::DoCommand(TDSHTTPContext, TDSHTTPRequest, TDSHTTPResponse)
Dshttpwebbroker::TDSRESTWebDispatcher::DispatchRequest(TObject, Web::Httpapp::TWebRequest, Web::Httpapp::TWebResponse)
Note: This depends entirely on your usage of DataSnap. In the above case requests are passed into the DataSnap API through TDSRESTWebDispatcher (comming from TIdCustomHTTPServer).
Every Exception raised in a ServerMethod will end up in TDSService::ProcessRequest.
In this procedure every Exception is caught and ONLY its Message is added to a TRequestCommandHandler->CommandList.
Further down the Message is written as JSON/DBX command to the output.
So we can never handle the Exception Object and access the StackTrace or other information. So this alone is unacceptable and has to change
The good news is, that this procedure is virtual and can be overwritten. The bad news is, that in the example above you would have to extend TDSRESTService with your own ProcessRequest procedure (including your errorhandler), TDSRESTServer with own DoDSRESTCommand (in there the TDSRESTService is created in a monstrously large procedure) and TDSRESTWebDispatcher (depending on your usage).
My personal recommendation is to don't use DataSnap.
Note: At the point of writing this, I haven't found any invoke of the OnError event.
I'm geting following exception while extracting Twitter data using Flume on CDH4.
twitter4j.TwitterStreamImpl: Receiving status stream. Exception in
thread "Twitter4J Async Dispatcher[0]" java.lang.NoSuchMethodError:
twitter4j.json.JSONObjectType.determine(Ltwitter4j/internal/org/json/JSONObject;)Ltwitter4j/json/JSONObjectType;
at
twitter4j.AbstractStreamImplementation$1.run(AbstractStreamImplementation.java:100)
at
twitter4j.internal.async.ExecuteThread.run(DispatcherImpl.java:116)
I was getting the same issue in my code, but when I changed the .jar from twitter4j-core-2.2.6.jar to twitter4j-stream-3.0.0.jar it got resolved.
The main reason behind this issue was due to FilterQuery fq = new FilterQuery(); was used in the code and FilterQuery class is present in twitter4j-core-2.2.6.jar but it has some problem and due to this the issue was coming. If we replace the twitter4j-core-2.2.6.jar with twitter4j-stream-3.0.0.jar then it also contains FilterQuery class and issue gets solved.
Have a system build using C++ Builder 2010 that after running for about 20 hours it starts firing of assertion failures.
Assertion failed: xdrPtr && xdrPtr == *xdrLPP, file xx.cpp, line 2349
Tried google on it like crazy but not much info. Some people seem to refer a bunch of different assertions in xx.cpp to shortcomings in the exception handling in C++ Builder. But I haven't found anything referencing this particular line in the file.
We have integrated madExcept and it seems like somewhere along the way this catches an out of memory exception, but not sure if it's connected. No matter what an assertion triggering doesn't seem correct.
Edit:
I found an instance of a if-statement that as part of it's statement used a function that could throw an exception. I wonder if this could be the culprit somehow messing up the flow of the exception handling or something?
Consider
if(foo() == 0) {
...
}
wrapped in a try catch block.
If an exception is thrown from within foo() so that no int is returned here how will the if statement react? I'm thinking it still might try to finish executing that line and this performing the if check on the return of the function which will barf since no int was returned. Is this well defined or is this undefined behaviour?
Wouldn't
int fooStatus = foo();
if(fooStatus == 0) {
...
}
be better (or should I say safer)?
Edit 2:
I just managed to get the assertion on my dev machine (the application just standing idle) without any exception about memory popping up and the app only consuming around 100 mb. So they were probably not connected.
Will try to see if I can catch it again and see around where it barfs.
Edit 3:
Managed to catch it. First comes an assertion failure notice like explained. Then the debugger shows me this exception notification.
If I break it takes me here in the code
It actually highlights the first code line after
pConnection->Open();
But it seems I can change this to anything and that line is still highlighted. So my guess is that the error is in the code above it somehow. I have seen more reports about people getting this type of assertion failure when working with databases in RAD Studio... hmmmm.
Update:
I found a thread that recursively called it's own Execute function if it wasn't able to reach the DB server. I think this is at least part of the issue. This will just keep on trying and as more and more worker threads spawn and also keep trying it can only end in disaster.
If madExcept is hinting that you have an out of memory condition, the assert could fail if the pointers are NULL (i.e. the allocation failed). What are the values of xdrPtr and xdrLPP when the assert occurs? Can you trace back to where they are allocated?
I would start looking for memory leaks.
(edit: this question is about BB specifically, because of the strange way it optimises exceptions. I am comfortable with normal exception handling patterns in J2SE, but BB does not behave as per normal. Specifically in this case, BB discards the error type, and message, and how BB devs try to deal with this issue, or if they ignore it.)
I would like to implement some form of custom global error handling in my BB app. Specifically to try to handle any other exceptions that were not caught by my code, because I had not expected them. The default behaviour is that the app fails, and a dialog pops up saying an Unknown error occured.
I would like to describe the error a little bit better, hence my term "global error handler". Something similar to the code:
public static void main(String[] args)
{
try
{
FusionApp app = FusionApp.getInstance();
app.enterEventDispatcher();
}
catch (Throwable t)
{
// t has lost all type information at this point - this prints "null"
System.err.println(t.getMessage());
}
}
My immediate problem is that when I catch t (in the main() method after the app.enterEventDispatcher() call), it has lost its type information. e.g. I know that the code throws an IllegalArgumentException with a custom message - however in the catch block, it is a java.lang.Error with null message.
And in the stack trace (ALT LGLG), the message has also been lost (at least the stack trace is accurate).
So... what is a good pattern to use to implement some form of global error handling on BB? Or is this considered a bad idea on this platform?
Is it considered good practice to just have the unknown error dialog box pop up - I don't like this, but maybe that is the way of the BB?
Best practices are to implement custom exception handling.
So, if you expecting to catch IllegalArgumentException, MyCustomException and StartupException, put them into catch block first, and then put an Exception catch (and then, if you like, put a Throwable catch)
The common rule is - from most exclusive to most common, and for exceptions of the same level - from most expected to least expected.
In case of exception == null or getMessage() == null you can always display something like "Application error, please send event log to [support email]" message, then if you have a nice event logging in you app, you have a good chance to reproduce an issue.
And talking about event log, see EventLogger class to implement logging.