Webapi 2 global exception handling not raised - c#-4.0

I'm uising web api 2 to develop services for a client, to manage errors we are using a ExceptionsFilterAttribute, but as you know, in this level not all exception are catched.
Some errors are raised in protected void Application_AuthenticateRequest(Object sender, EventArgs e) and I want to handle them and send a custom message to our client to give him more details about the error, to solve this I create a GlobalExceptionHandler
public class GlobalExceptionHandler: ExceptionHandler
{
//A basic DTO to return back to the caller with data about the error
private class ErrorInformation
{
public string Message { get; set; }
public DateTime ErrorDate { get; set; }
}
public override void Handle(ExceptionHandlerContext context)
{
//Return a DTO representing what happened
context.Result = new ResponseMessageResult(context.Request.CreateResponse(HttpStatusCode.InternalServerError,
new ErrorInformation { Message="We apologize but an unexpected error occured. Please try again later.", ErrorDate=DateTime.UtcNow }));
//This is commented out, but could also serve the purpose if you wanted to only return some text directly, rather than JSON that the front end will bind to.
//context.Result = new ResponseMessageResult(context.Request.CreateResponse(HttpStatusCode.InternalServerError, "We apologize but an unexpected error occured. Please try again later."));
}
}
In WebApiConfig i added this line :
config.Services.Replace(typeof(IExceptionHandler), new GlobalExceptionHandler());
The the Application_AuthenticateRequest raise some errors but GlobalExceptionHandler is never reached.
Do you have any idea how can I solve this issue ?
Thanks in advance.

Application_AuthenticateRequest does not come in the Web API pipeline. So if an exception is thrown in this method those can be caught by the Web API exception handler, because the exception is thrown before the Web API pipeline is started.
There are two ways to do this:
Either change the authentication mechanism and use Web API Authentication(IAuthenticationFilter) instead of Application_AuthenticateRequest.
If this project has only Web API related controllers, not like MVC and all.
Or use Application_Error in the Global.asax.cs file to catch the exception thrown in Application_AuthenticateRequest

Related

Calling #Asynchronous metod from library on Wildfly Linux

I've encounter some problem while applying a small library to send email using wildfly email resource
Idea with library is to provide singleton providing asynchronous method to send emails.
in short service looks like
#Singleton
public class MailService {
private static final String MIME_TYPE = "text/html; charset=utf-8";
private static final Logger LOG = Logger.getLogger(MailService.class.getName());
#Inject
private Session session;
#Asynchronous
public void sendEmail(final EmailModel email) {
try {
MimeMessage message = new MimeMessage(session);
if (email.normalRecipientsListIsEmpty()) {
throw new RuntimeException("need destination address.");
}
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(email.getNormalRecipients()));
message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(email.getCCRecipients()));
message.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(email.getBCCRecipients()));
message.setSubject(email.getSubject());
message.setContent(email.getContent(), MIME_TYPE);
Transport.send(message);
} catch (MessagingException e) {
throw new RuntimeException("Failed to sen email.", e);
}
}
}
Injected session is produced in project via #Produces annotation in Stateless service field.
While on windows everything works fine, however if deployed on wildfly running on linux, there is an timeout exception with message like "could not obtain a lock on method within 5000milis"
When i moved whole code to project, with no changes, everything started to work perfectly.
My question is, why is this happening? Is there a difference in implementation somewhere or in configuration? How can i fix that and move code back to library where it can be reused in other projects?

How can I test a MessageBodyWriter for a List<Some>?

I have a JAX-RS resource method.
#GET
#Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public List<Some> list() {
final List<Some> list = get();
// list and each elements are ok.
return list;
}
The problem is that application/xml generates an 500 without any specific server(tomcat) log.
application/json works fine.
I check JAXB-marshaller for every element in list.
How can I debug this? How can I test any MessageBodyWriter for List<Some>?
UPDATE
The root cause of this problem (500 without a error log) is a wrongly JAXB-annotated class.
I created an ExceptionMapper<Exception> as #peeskillet suggested.
#Provider
public class MyExceptionMapper implements ExceptionMapper<Exception> {
#Override
public Response toResponse(final Exception exception) {
exception.printStackTrace(System.err);
return Response.serverError().build();
}
}
Then I could see what error JAXB made. I still don't understand why any JAXB-error is not reported.
"How can I debug this?"
Sometimes when errors/exceptions aren't being logged, I'll create an
ExceptionMapper<Throwable or Exception>
and just print the stack trace. If the exception is being thrown in the JAX-RS context, it should go through the mapper.
See more about exception mapping

ETW events in Azure diagnostics (SDK 2.5) are logged with incorrect / missing schema

I upgraded to Azure SDK 2.5 and switched to semantic logging with EventSources.
Logging works locally with a custom EventListener.
When deployed, logs are written to a storage table, but only the EventId, Pid, Tid etc. are populated, the really interesting fields (Message, Task, Keyword, Opcode) are left blank.
The diagnostics infrastructure log is full of errors with regards to ETW, but I don't know what to make of them:
Failed to load backup EventSource manifest file C:\Resources\{13b7ec61-6424-d4d3-9972-a83e58d8d6bb}\directory\f71b19461fcf494d89d3717b3a13cadf. something.WorkerRole.DiagnosticStore\WAD0103\Configuration\EventSource_Manifest_fe06b63d-39aa-5419-0529-18c4dacf4f68_Ver_20.backup.xml;
EventSource events will be logged without a proper schema until provider sends the manifest packets
Load manifest file failed for C:\Resources\{13b7ec61-6424-d4d3-9972-a83e58d8d6bb}\directory\f71b19461fcf494d89d3717b3a13cadf.something. WorkerRole. DiagnosticStore\WAD0103\Configuration\EventSource_Manifest_fe06b63d-39aa-5419-0529-18c4dacf4f68_Ver_20.xml
Failed to manage manifest version for file C:\Resources\{13b7ec61-6424-d4d3-9972-a83e58d8d6bb}\directory\f71b19461fcf494d89d3717b3a13cadf. something. WorkerRole.DiagnosticStore\WAD0103\Configuration\EventSource_Manifest_fe06b63d-39aa-5419-0529-18c4dacf4f68_Pid_3436.xml
Failed to process EventSource manifest event GUID:fe06b63d-39aa-5419-0529-18c4dacf4f68, event id:0xFFFE
Change in the number of events lost since the last sample: EventsCaptured=2 EventsLogged=1 EventsLost=0
I do not use a manifest file and specify the EventSource via class / attribute name:
<EtwEventSourceProviderConfiguration scheduledTransferPeriod="PT3M" scheduledTransferLogLevelFilter="Information" provider="something.Core">
<DefaultEvents eventDestination="CoreEvents" />
</EtwEventSourceProviderConfiguration>
I must be missing something, but I do not know what.
The remaining diagnostic services all work (infrastructure logs, performance counter etc.).
The EventId that is being logged is the correct one, but all the important information of the log is missing, I suppose because of an incomplete configuration?
Edit: here is my EventSource code. I won't post the entire thing because it's quite large. I use another type that calls the EventSource methods and handles formatting of parameters (if the source is enabled in that level). Most method arguments are of type string, there are no objects or other complex types passed around (that handles the other type).
[EventSource(Name = "something.Core")]
public sealed class CoreEventSource : EventSource {
private static readonly CoreEventSource SoleInstance = new CoreEventSource();
static CoreEventSource() {}
private CoreEventSource() {}
public static CoreEventSource Instance {
get { return SoleInstance; }
}
public static EventKeywords AllKeywords = (EventKeywords)(-1);
public class Keywords {
public const EventKeywords None = (EventKeywords)(1 << 1);
public const EventKeywords Infrastructure = (EventKeywords)(1 << 2);
[...]
}
public class Tasks {
public const EventTask None = EventTask.None;
// generic operations
public const EventTask Create = (EventTask)11;
public const EventTask Update = (EventTask)12;
public const EventTask Delete = (EventTask)13;
public const EventTask Get = (EventTask)14;
public const EventTask Put = (EventTask)15;
public const EventTask Remove = (EventTask)16;
public const EventTask Process = (EventTask)17;
}
[Event(1, Message = "Initialization of {0} failed: {1}.", Level = EventLevel.Critical, Keywords = Keywords.Infrastructure)]
public void CriticalInitializationFailure(string component, string details, string exception) {
this.WriteEvent(1, component, details, exception);
}
[Event(2, Message = "[Role '{0}'] Startup: {1}", Level = EventLevel.Informational, Keywords = Keywords.Infrastructure)]
public void RoleStartup(string roleName, string message) {
this.WriteEvent(2, roleName, message);
}
[Event(3, Message = "[Role '{0}'] Stop failed: {1}.", Level = EventLevel.Error, Keywords = Keywords.Infrastructure)]
public void RoleStopFailed(string roleName, string details, string exception) {
this.WriteEvent(3, roleName, details, exception);
}
[Event(4, Message = "An unhandled exception occurred.", Level = EventLevel.Critical, Keywords = Keywords.Infrastructure)]
public void UnhandledException(string exception) {
this.WriteEvent(4, exception);
}
[Event(5, Message = "An unobserved exception occurred in a faulted task.", Level = EventLevel.Critical, Keywords = Keywords.Infrastructure)]
public void UnobservedTaskException(string exception) {
this.WriteEvent(5, exception);
}
[...]
}
Turns out there were quite a few problems with my EventSource. The first thing I'd recommend to anyone working with ETW is to use the Microsoft TraceEvent Library from NuGet, even if you use System.Diagnostics.Tracing, because it comes with a tool that will verify your EventSource code and notify you about problems.
I had to fix the following:
EventSource names must not contain a period .
Task/Opcode pairs must be unique within an EventSource
One must not declare a None field in a custom Keywords or Tasks enumeration
Hope this is of some use to anyone who encounters a similar problem.
Another thing that should be taken care of (which fixed our case)
- EventSources should only have a Name or a Guid, not both.
In our case, having both caused
- The EtwEventSourceProvider to not log anything
- The EtwEventManifestProvider to log the same way you outlined, with empty data points.

Is it possible to make servicestack use an unbuffered response stream?

I want to send messages back to a client via a stream. I want the client to start processing these messages as soon as possible (before the server has completed the streaming on the server side).
I have implemented IStreamWriter and I have a service which returns the IStreamWriter implementation.
public class StreamingService : Service
{
public object Any(MyStreamRequest request)
{
return new MyStreamWriter(request);
}
}
Where MyStreamRequest is defined like this:
[DataContract]
public class StreamRequest : IReturn<Stream>
{
[DataMember]
public int HowManySecondsToProduceData { get; set; }
}
When I test my implementation in a self-hosted environment it works perfectly. However, when I host this in IIS, the get call from the client
var client = new ProtoBufServiceClient("");
Stream stream = client.Get(new StreamRequest { HowManySecondsToProduceData = 20};
does not return until the IStreamWriter.WriteTo call returns (20 seconds in the sample above). This prevents my client from processing the stream right away and will also cause failure in high volume cases. I do call responseStream.Flush() inside my IStreamWriter.WriteTo implementation.
Does anybody have any insight on why this does not work in the IIS scenario, but only for the self hosted case? What do I need to do differently?
It seems like a likely cause of this problem is that the servicestack response stream is set to use buffering. I cannot find a way to change this though. Is it possible?
You just need to disable ASP.Nets response buffering:
public class NoBufferAttribute : RequestFilterAttribute
{
public override void Execute( IHttpRequest req, IHttpResponse res, object requestDto )
{
var originalResponse = (System.Web.HttpResponse)res.OriginalResponse;
originalResponse.BufferOutput = false;
}
}
John
I found a solution myself: The solution to this problem is quite simple: Call IHttpResponse Flush() inside the IStreamWriter.WriteTo implementation when you want to send data to the client. You get the IHttpResponse by calling base.Response inside the Service implementation.

Error Handling Strategy for Sandboxed SharePoint Solutions

I am looking to develop an error handling strategy for a SharePoint solution that makes use of sandboxed webparts. I was initially looking at a general exception handling approach based on this article, but this doesn't work for sandboxed webparts. Once an unhandled exception has been thrown in the sandbox, the user code service appears to take control, so that the exception handling in the base web part isn't reached. Are there any established error handling approaches for sandboxed solutions?
Is anyone aware of a method of determining when an unhandled exception has been thrown in a sandboxed webpart, if only to change the displayed error message to a more user friendly message? I would like to replace the standard "Web Part Error: Unhandled exception was thrown by the sandboxed code wrapper's Execute method in the partial trust app domain: An unexpected error has occurred." message at very least.
Thanks, MagicAndi.
Actually, you can follow the approach suggested by the article you mentioned. You just have to provide safe overridables for all virtual properties and methods your descendant web parts are going to override. The patter can be described:
Override and seal every virtual property and method supposed to be overriden with code that can throw an exception.
Create a virtual counterpart of the overridable with the same prototype and call the base class from it if necessary. This is supposed to be overriden by your descendants.
Call the new overridable from the sealed member in a try&catch and remember the exception if caught there.
Rendering method either renders the usual content or the remembered error message.
This is a torso of the base class I use:
public class ErrorSafeWebPart : WebPart {
#region Error remembering and rendering
public Exception Error { get; private set; }
// Can be used to skip some code later that needs not
// be performed if the web part renders just the error.
public bool HasFailed { get { return Error != null; } }
// Remembers just the first error; following errors are
// usually a consequence of the first one.
public void RememberError(Exception error) {
if (Error != null)
Error = error;
}
// You can do much better error rendering than this code...
protected virtual void RenderError(HtmlTextWriter writer) {
writer.WriteEncodedText(Error.ToString());
}
#endregion
#region Overriddables guarded against unhandled exceptions
// Descendant classes are supposed to override the new DoXxx
// methods instead of the original overridables They should
// not catch exceptions and leave it on this class.
protected override sealed void CreateChildControls() {
if (!HasFailed)
try {
DoCreateChildControls();
} catch (Exception exception) {
RememberError(exception);
}
}
protected virtual void DoCreateChildControls()
{}
protected override sealed void OnInit(EventArgs e) {
if (!HasFailed)
try {
DoOnInit(e);
} catch (Exception exception) {
RememberError(exception);
}
}
protected virtual void DoOnInit(EventArgs e) {
base.OnInit(e);
}
// Continue similarly with OnInit, OnLoad, OnPreRender, OnUnload
// and/or others that are usually overridden and should be guarded.
protected override sealed void RenderContents(HtmlTextWriter writer) {
// Try to render the normal contents if there was no error.
if (!HasFailed)
try {
DoRenderContents(writer);
} catch (Exception exception) {
RememberError(exception);
}
// If an error occurred in any phase render it now.
if (HasFailed)
RenderError(writer);
}
protected virtual void DoRenderContents(HtmlTextWriter writer) {
base.RenderContents(writer);
}
#endregion
}
--- Ferda

Resources