Outlook 2016 VSTO-Addin: How to avoid System.AccessVioloationExceptionfor "outdated" link to AppointmentItem? - outlook-addin

As you can see I checked for appointmentItem != null and rtfBody.Length != 0
although the call to appointmentItem.GetInspector throws a System.AccessVioloationException.
This happens when I run my Outlook addon via VisualStudio for a longer time (several hours) and then close Outlook.
My idea is that this is caused by the fact that Outlook is already shutting down, thus the AppointmentItem still exists but some COM related things are out of order. But this is only a vague guess.
Do you have any idea why this happens and how to avoid this?
Furthermore I already added a try/catch like:
catch (Exception ex)
{
log.Info(ex.Message);
return 0;
}
But the exception does not get caught. So I need to additionally catch SystemExceptions explicitly I understand, right?

This happens when I run my Outlook addon via VisualStudio for a longer time (several hours) and then close Outlook.
The common language runtime exposes COM objects through a proxy called the runtime callable wrapper (RCW). Although the RCW appears to be an ordinary object to .NET clients, its primary function is to marshal calls between a .NET client and a COM object. So, if the COM server doesn't exist (Outlook is closed) your calls to the RCW don't make any sense.
By default, starting from .NET 4.0, the common language runtime (CLR) does not deliver these exceptions to managed code, and the try/catch blocks (and other exception-handling clauses) are not invoked for them. If you are absolutely sure that you want to maintain your handling of these exceptions, you must apply the HandleProcessCorruptedStateExceptionsAttribute attribute to the method whose exception-handling clauses you want to execute. The CLR delivers the corrupted process state exception to applicable exception clauses only in methods that have both the HandleProcessCorruptedStateExceptionsAttribute and SecurityCriticalAttribute attributes.
You can also add the <legacyCorruptedStateExceptionsPolicy> element to your application's configuration file. This will ensure that corrupted state exceptions are delivered to your exception handlers without the HandleProcessCorruptedStateExceptionsAttribute or SecurityCriticalAttribute attribute. This configuration element has no effect on applications that were compiled in versions previous to the .NET Framework 4 but are running in the .NET Framework 4 or later; corrupted state exceptions will continue to be delivered for those applications. The HandleProcessCorruptedStateExceptionsAttribute attribute is ignored when it is encountered in partially trusted or transparent code, because a trusted host should not allow an untrusted add-in to catch and ignore these serious exceptions.
For more information about corrupted process state exceptions, see the entry Handling Corrupted State Exceptions in the CLR Inside blog.
You can also handle the following events of the AppDomain class:
AppDomain.UnhandledException is fired when an exception is not caught. Starting with the .NET Framework 4, this event is not raised for exceptions that corrupt the state of the process, such as stack overflows or access violations, unless the event handler is security-critical and has the HandleProcessCorruptedStateExceptionsAttribute attribute.
AppDomain.FirstChanceException is fired when an exception is thrown in managed code, before the runtime searches the call stack for an exception handler in the application domain.

Related

WCF: use or not to use exception from service to client in production? any alternative?

I am thinking in use some exceptions to from service to client.
I am thinking for example in this case. The client try to insert a register in the database. This register has a value for e filed that exists in the database, and how it has a unique constraint, when I do the savechanges I get an updateException.
I am thinking to use exceptions (faultException) to warn to client of the error, and use a custom class to send to the client the actual data of the register, so in this way the client does not to make other query for the register.
However, in this link, it says that exceptions only should be used in development, no in production, so, without exceptions, how could I do what I want to do?
Perhaps I could use a custom class, that have one list property for each type of entities, and a property bool, that indicates if the operation is right or wrong, other property with an arbitrary code to indicate the type of error... etc. This is a good alternative?
In summary, really is better avoid exceptions in production? how I could communicate to the client errors from the service?
You have 2 options:
Throw exceptions and return WCF faults
Attach error information to you return objects
I personally favour throwing exceptions and returning WCF faults. I dont like the idea of attaching error information to return objects, I feel it violoates object oriented principals. For example a field called 'ErrorCode' has no place on a 'CustomerAddress' object.
I believe that if exceptional circustances arise, then an exception should be thrown. This will also simplfy your code as you wont have to wrap everything in try catch blocks in order to attach error information to your return object. Although you may want to catch unexpected exceptions and then throw a more appropriate exception with a more useful message.

Handling ObjectDisposedExceptions on disconnected WCF channels

When a method is called on a WCF channel that has been disconnected for some reason, it raises an ObjectDisposedException.
Now is normal operation this should not happen, but if for some reason it did, I would like to be able to handle the exception nicely by showing an error to the user like "An operation failed because the service is not connected".
The problem is I just get a generic disposed exception in my appwide exception handler, so I have no way of determining whether WCF threw it.
to get around this I currently have a wrapper class that simply wraps all service method calls with try/catch and rethrows any ObjectDisposedException's as a custom comms exception that my global handler can deal with. this is a load of boilerplate stuff I could do without though.
Is there any way of determining whether WCF threw the exception?
Cheers
I used to encounter such problem, it seems it's difficult to determine whether the WCF throws exception. You can't use the CommunicationObject.Status for this problem, only when you try to use that channel, it throws exception to tell you that the channel is faulted.
Therefore, I used the way like yours.

What is the easiest way to log exceptions from a WCF service to a the Windows Event Log?

I want to log all exceptions (including serialization exception stack traces) in a WCF server to the Windows Event Log (log4net logging would also be acceptable).
What is the easiest way to do this?
Specifically all errors in serialization, in the service itself, etc. Right now I'm using tracing to get serialization errors during development. Tracing was the only way I could find out what object was actually have a problem with serialization. See Quickly finding WCF Serialization/Deserialization Issues for an example of getting the serialization stack trace.
I can handle errors in the service code itself. However, errors in the WCF machinery don't propagate to my service code (like serialization errors).
I don't need to send the errors to the client.
I just want to get the errors into one location (like the Event Log).
Right now (from my research) it appears that the IErrorHandler Interface with some custom code might be the best way to proceed. Will using the IErrorHandling interace catch the serialization exceptions?
Edit:
This may be the answer I'm looking for:
How do I create a global exception handler for a WCF Services?
I'd just like a confirmation that this will catch serialization errors and more importantly the details of those errors, also.
More Info:
How do I create a global exception handler for a WCF Services?
Yes, IErrorHandler will also catch serialization exceptions. You will get all information stored in the exception. Whether or not this enough detail for you, I can't say.
Note that there may be client-side errors (serialization and others) which will never make it to the server. You will not see those with the IErrorHandler.

Occasional error on production server: Method <name> is not supported on this proxy

One of 4 production servers once in a while generates tons of error claiming:
Method RunRules is not supported on this proxy, this can happen if the method is not marked with OperationContractAttribute or if the interface type is not marked with ServiceContractAttribute.
The method "RunRules" is one of the methods in wcf [ServiceContract] interface, and it is marked as [OperationContract].
Before this error, in the same method, occasionally it would get a wrong service through castle container. After I put more logging information to nail down exact cause, it mutated into the current error.
It is a webservice the error comes out of, it tries to call into a windows service through wcf endpoint when this happens. And this only happens on one specific machine. The frequency is about once a week or 2 weeks. Once recycle of the webservice happens (3 hours), the error stops.
To me it is almost like corrupted vtable. Just wondering, how would you approach this problem? Hate to ask IT people start to re-image the machine without solid proof.
Thanks!
No simple answer for such abstract magic error, so try out logging entire call stack, especially internal Castle DLL calls, if standart exception does not contain such deep call stack information - use reflection.
// use this in loop incrementing levelIndex up to st.FrameCount
// to grab all possible callstack entries
StackTrace st = new StackTrace();
st.GetFrame(levelIndex).GetMethod().Name;
Then using utility like ILSpy disassemble Castle DLL and try out analyze which state causes concrete execution flow which ends up with exception you got.
If you able log callstack - please share so I would be able check it as well.

Silverlight and WCF: Handle 'WCF down' exception / WCF connection check

Inside my Silverlight app, I'm calling a web service asynchronously, using the client generated for me by Visual Studio (Add Service Reference...).
My code looks like this:
ServiceClient serviceClient = new ServiceClient();
serviceClient.GetServerTimeCompleted += new EventHandler<GetServerTimeCompletedEventArgs>(serviceClient_GetServerTimeCompleted);
serviceClient.GetServerTimeAsync();
void serviceClient_GetServerTimeCompleted(object sender, GetServerTimeCompletedEventArgs e)
{
// do nothing atm
}
Everything works fine as long as the service is up and running, but when the service isn't running, i get:
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
"An exception occurred during the
operation, making the result invalid.
Check InnerException for exception
details."
InnerException
"An error occurred while trying to
make a request to URI
'http://'. This could be
due to attempting to access a service
in a cross-domain way without a proper
cross-domain policy in place, or a
policy that is unsuitable for SOAP
services. You may need to contact the
owner of the service to publish a
cross-domain policy file and to ensure
it allows SOAP-related HTTP headers to
be sent. This error may also be caused
by using internal types in the web
service proxy without using the
InternalsVisibleToAttribute attribute.
Please see the inner exception for
more details."
It makes sense that I get an exception under these circumstances, but what I can't figure out is how to catch the exception in my client code. Is there a standard way to do this? If I understand how this is working, when my code calls the generated code, it spawns another thread that actually calls the web service and waits for the response. The exception is in that thread and in the generated code. Neither my calling code (see above) or my callback method have the opportunity to see the exception.
Thanks
Christian
There are a number of reasons not to use the "Add Service Reference" functionality in Visual Studio. Here's a good (and long) article on the issues, and how to use WCF creating your clients. I'm working through these issues myself, right now.
Among the concerns about "Add Service Reference" include code bloat in the downloadable client .XAP file, difficulty in maintaining generated code, difficulty in staging or shipping code when the server addresses and ports are hard-coded in the client config file (also embedded in the .XAP), and lots more. Building your own clients will also give you better capability to manage exceptions in client code.
There are some tradeoffs; you'll need to make your data contract classes portable to the Silverlight environment. (You can't just add a reference to a server-side .NET assembly; it doesn't work.) There same site linked above has a good article on re-using assemblies in Silverlight, but probably the easiest way to deal with this is to add links to your server-side classes from your Silverlight project. (In the Silverlight project, right-click and Add -> Add existing item... and find the item you want to include, but instead of clicking on the Add button, click the down-arrow beside it and click on "Add as Link".) Watch out for other references and using statements that refer to server-side classes; you may need to do conditional compiles so that your data contract classes compile cleanly in the client-side project.
Overall, it really looks like a cleaner way to go, especially for large projects that may use lots of service contracts and data contracts, or where you need to ship your Silverlight projects as part of a commercial application that runs on other people's servers. It should also be a lot cleaner for testability, especially for integration and staging testing.
I have encountered this problem before - you need to add exception handling code around your ServiceClient setup code. I typically check for the following CommunicationException, TimeoutException, and EndpointNotFoundException and provide the user with an appropriate dialog telling them something is broken:
ServiceClient serviceClient;
try
{
serviceClient = new ServiceClient();
serviceClient.GetServerTimeCompleted += new EventHandler<GetServerTimeCompletedEventArgs>(serviceClient_GetServerTimeCompleted);
serviceClient.GetServerTimeAsync();
}
catch (EndpointNotFoundException ex)
{
// log exception
// show error dialog
}
Note: this will not handle errors encountered during the asnchronous method callback - it will need it's own (similar) exception handling.
Actually you have to put crossdomainaccesspolicy.xml in IIS default website root folder.
you copy the given below xml content and save in the name of ClinetAccespolicy.xml and then put on the IIS default website root folder.