Source/NFX.Wave/Filters/ErrorFilter.cs
/// <summary>
/// Handles the exception by responding appropriately with error page with conditional level of details and logging
/// </summary>
Handles the exception by responding appropriately with error page with conditional level of details and logging
Handles the exception by responding appropriately with error page with conditional level of details and logging
public static void HandleException(WorkContext work,
                                         Exception error,
                                         OrderedRegistry<WorkMatch> showDumpMatches,
                                         OrderedRegistry<WorkMatch> logMatches,
                                         string securityRedirectURL = null,
                                         string securityRedirectTarget = null,
                                         OrderedRegistry<WorkMatch> securityRedirectMatches = null,
                                         Type customPageType = null
                                         )
      {
          if (work==null || error==null) return;
          var showDump = showDumpMatches != null ?
                         showDumpMatches.OrderedValues.Any(m => m.Make(work)!=null) : false;
          if (work.Response.Buffered)
            work.Response.CancelBuffered();
          var json = false;
          if (work.Request!=null && work.Request.AcceptTypes!=null)
               json = work.Request.AcceptTypes.Any(at=>at.EqualsIgnoreCase(ContentType.JSON));
          var actual = error;
          if (actual is FilterPipelineException)
            actual = ((FilterPipelineException)actual).RootException;
          if (actual is MVCException)
            actual = ((MVCException)actual).InnerException;
          var securityError = NFX.Security.AuthorizationException.IsDenotedBy(actual);
          if (actual is HTTPStatusException)
          {
            var se = (HTTPStatusException)actual;
            work.Response.StatusCode = se.StatusCode;
            work.Response.StatusDescription = se.StatusDescription;
          }
          else
          {
            if (securityError)
            {
              work.Response.StatusCode = WebConsts.STATUS_403;
              work.Response.StatusDescription = WebConsts.STATUS_403_DESCRIPTION;
            }
            else
            {
              work.Response.StatusCode = WebConsts.STATUS_500;
              work.Response.StatusDescription = WebConsts.STATUS_500_DESCRIPTION;
            }
          }
          if (json)
          {
             work.Response.ContentType = ContentType.JSON;
             work.Response.WriteJSON(error.ToClientResponseJSONMap(showDump));
          }
          else
          {
            if (securityRedirectMatches != null && securityRedirectMatches.Count > 0)
            {
              JSONDataMap matched = null;
              foreach(var match in securityRedirectMatches.OrderedValues)
              {
                matched = match.Make(work, actual);
                if (matched!=null) break;
              }
              if (matched!=null)
              {
                var url = matched[VAR_SECURITY_REDIRECT_URL].AsString();
                var target = matched[VAR_SECURITY_REDIRECT_TARGET].AsString();
                if (url.IsNotNullOrWhiteSpace())
                  securityRedirectURL = url;
                if (target.IsNotNullOrWhiteSpace())
                  securityRedirectTarget = target;
              }
            }
            if (securityRedirectURL.IsNotNullOrWhiteSpace() && securityError && !work.IsAuthenticated)
            {
              var url = securityRedirectURL;
              var target = securityRedirectTarget;
              if (target.IsNotNullOrWhiteSpace())
              {
                var partsA = url.Split('#');
                var parts = partsA[0].Split('?');
                var query = parts.Length > 1 ? parts[0] + "&" : string.Empty;
                url = "{0}?{1}{2}={3}{4}".Args(parts[0], query,
                  target, Uri.EscapeDataString(work.Request.Url.PathAndQuery),
                  partsA.Length > 1 ? "#" + partsA[1] : string.Empty);
              }
              work.Response.RedirectAndAbort(url);
            }
            else
            {
              WaveTemplate errorPage = null;
              if (customPageType!=null)
                try
                {
                  errorPage = Activator.CreateInstance(customPageType) as WaveTemplate;
                  if (errorPage==null) throw new WaveException("not WaveTemplate");
                }
                catch(Exception actErr)
                {
                  work.Log(Log.MessageType.Error,
                            StringConsts.ERROR_PAGE_TEMPLATE_TYPE_ERROR.Args(customPageType.FullName, actErr.ToMessageWithType()),
                            typeof(ErrorFilter).FullName+".ctor(customPageType)",
                            actErr);
                }
              if (errorPage==null)
                errorPage =  new ErrorPage(work, error, showDump);
              errorPage.Render(work, error);
            }
          }
          if (logMatches!=null && logMatches.Count>0)
          {
            JSONDataMap matched = null;
            foreach(var match in logMatches.OrderedValues)
            {
              matched = match.Make(work, error);
              if (matched!=null) break;
            }
            if (matched!=null)
              work.Log(Log.MessageType.Error, error.ToMessageWithType(), typeof(ErrorFilter).FullName, pars: matched.ToJSON(JSONWritingOptions.CompactASCII));
          }
      }
public static void HandleException ( WorkContext work , Exception error , OrderedRegistry < WorkMatch > showDumpMatches , OrderedRegistry < WorkMatch > logMatches , string securityRedirectURL = null , string securityRedirectTarget = null , OrderedRegistry < WorkMatch > securityRedirectMatches = null , Type customPageType = null ) { if ( work == null || error == null ) return ; var showDump = showDumpMatches != null ? showDumpMatches . OrderedValues . Any ( m => m . Make ( work ) != null ) : false ; if ( work . Response . Buffered ) work . Response . CancelBuffered ( ) ; var json = false ; if ( work . Request != null && work . Request . AcceptTypes != null ) json = work . Request . AcceptTypes . Any ( at => at . EqualsIgnoreCase ( ContentType . JSON ) ) ; var actual = error ; if ( actual is FilterPipelineException ) actual = ( ( FilterPipelineException ) actual ) . RootException ; if ( actual is MVCException ) actual = ( ( MVCException ) actual ) . InnerException ; var securityError = NFX . Security . AuthorizationException . IsDenotedBy ( actual ) ; if ( actual is HTTPStatusException ) { var se = ( HTTPStatusException ) actual ; work . Response . StatusCode = se . StatusCode ; work . Response . StatusDescription = se . StatusDescription ; } else { if ( securityError ) { work . Response . StatusCode = WebConsts . STATUS_403 ; work . Response . StatusDescription = WebConsts . STATUS_403_DESCRIPTION ; } else { work . Response . StatusCode = WebConsts . STATUS_500 ; work . Response . StatusDescription = WebConsts . STATUS_500_DESCRIPTION ; } } if ( json ) { work . Response . ContentType = ContentType . JSON ; work . Response . WriteJSON ( error . ToClientResponseJSONMap ( showDump ) ) ; } else { if ( securityRedirectMatches != null && securityRedirectMatches . Count > 0 ) { JSONDataMap matched = null ; foreach ( var match in securityRedirectMatches . OrderedValues ) { matched = match . Make ( work , actual ) ; if ( matched != null ) break ; } if ( matched != null ) { var url = matched [ VAR_SECURITY_REDIRECT_URL ] . AsString ( ) ; var target = matched [ VAR_SECURITY_REDIRECT_TARGET ] . AsString ( ) ; if ( url . IsNotNullOrWhiteSpace ( ) ) securityRedirectURL = url ; if ( target . IsNotNullOrWhiteSpace ( ) ) securityRedirectTarget = target ; } } if ( securityRedirectURL . IsNotNullOrWhiteSpace ( ) && securityError && ! work . IsAuthenticated ) { var url = securityRedirectURL ; var target = securityRedirectTarget ; if ( target . IsNotNullOrWhiteSpace ( ) ) { var partsA = url . Split ( ' ' ) ; var parts = partsA [ 0 ] . Split ( ' ' ) ; var query = parts . Length > 1 ? parts [ 0 ] + " " : string . Empty ; url = " " . Args ( parts [ 0 ] , query , target , Uri . EscapeDataString ( work . Request . Url . PathAndQuery ) , partsA . Length > 1 ? " " + partsA [ 1 ] : string . Empty ) ; } work . Response . RedirectAndAbort ( url ) ; } else { WaveTemplate errorPage = null ; if ( customPageType != null ) try { errorPage = Activator . CreateInstance ( customPageType ) as WaveTemplate ; if ( errorPage == null ) throw new WaveException ( " " ) ; } catch ( Exception actErr ) { work . Log ( Log . MessageType . Error , StringConsts . ERROR_PAGE_TEMPLATE_TYPE_ERROR . Args ( customPageType . FullName , actErr . ToMessageWithType ( ) ) , typeof ( ErrorFilter ) . FullName + " " , actErr ) ; } if ( errorPage == null ) errorPage = new ErrorPage ( work , error , showDump ) ; errorPage . Render ( work , error ) ; } } if ( logMatches != null && logMatches . Count > 0 ) { JSONDataMap matched = null ; foreach ( var match in logMatches . OrderedValues ) { matched = match . Make ( work , error ) ; if ( matched != null ) break ; } if ( matched != null ) work . Log ( Log . MessageType . Error , error . ToMessageWithType ( ) , typeof ( ErrorFilter ) . FullName , pars : matched . ToJSON ( JSONWritingOptions . CompactASCII ) ) ; } }
Handles the exception by responding appropriately with error page with conditional level of details and logging
Handles the exception by responding appropriately with error page with conditional level of details and logging
//if needed for some edge HttpListener cases when Request or Request.AcceptTypes are null
work
WorkContext
error
Exception
showDumpMatches
OrderedRegistry<WorkMatch>
logMatches
OrderedRegistry<WorkMatch>
securityRedirectURL
string
securityRedirectTarget
string
securityRedirectMatches
OrderedRegistry<WorkMatch>
customPageType
Type