/// <summary> /// Constructs an exception based on a service fault. /// </summary> /// <param name="serviceFault">The fault received from a service.</param> /// <returns>The constructed exception.</returns> private static Exception GetExceptionFromServiceFault(DomainServiceFault serviceFault) { // Status was OK but there still was a server error. We need to transform // the error into the appropriate client exception if (serviceFault.IsDomainException) { return(new DomainException(serviceFault.ErrorMessage, serviceFault.ErrorCode, serviceFault.StackTrace)); } else if (serviceFault.ErrorCode == 400) { return(new DomainOperationException(serviceFault.ErrorMessage, OperationErrorStatus.NotSupported, serviceFault.ErrorCode, serviceFault.StackTrace)); } else if (serviceFault.ErrorCode == 401) { return(new DomainOperationException(serviceFault.ErrorMessage, OperationErrorStatus.Unauthorized, serviceFault.ErrorCode, serviceFault.StackTrace)); } else { // for anything else: map to ServerError return(new DomainOperationException(serviceFault.ErrorMessage, OperationErrorStatus.ServerError, serviceFault.ErrorCode, serviceFault.StackTrace)); } }
/// <summary> /// Based on custom error settings, restrict the level of information /// returned in each error. /// </summary> /// <remarks> /// This method will also trace the exception if tracing is enabled. /// </remarks> /// <param name="validationErrors">The collection of errors to process.</param> /// <param name="hideStackTrace">same as <see cref="HttpContext.IsCustomErrorEnabled"/> <c>true</c> means dont send stack traces</param> /// <returns>An exception representing the validation errors.</returns> internal static FaultException <DomainServiceFault> CreateFaultException(IEnumerable <ValidationResult> validationErrors, bool hideStackTrace) { Debug.Assert(validationErrors != null, "validationErrors is null."); DomainServiceFault fault = new DomainServiceFault(); IEnumerable <ValidationResultInfo> errors = validationErrors.Select(ve => new ValidationResultInfo(ve.ErrorMessage, ve.MemberNames)).ToList(); fault.OperationErrors = errors; // if custom errors is turned on, clear out the stacktrace. foreach (ValidationResultInfo error in errors) { if (hideStackTrace) { error.StackTrace = null; } } FaultException <DomainServiceFault> ex = new FaultException <DomainServiceFault>(fault, new FaultReason(new FaultReasonText(fault.ErrorMessage ?? String.Empty, CultureInfo.CurrentCulture))); return(ex); }
/// <summary> /// Transforms the specified exception as appropriate into a fault message that can be sent /// back to the client. /// </summary> /// <remarks> /// This method will also trace the exception if tracing is enabled. /// </remarks> /// <param name="e">The exception that was caught.</param> /// <returns>The exception to return.</returns> internal static FaultException <DomainServiceFault> CreateFaultException(Exception e) { Debug.Assert(!e.IsFatal(), "Fatal exception passed in"); DomainServiceFault fault = new DomainServiceFault(); HttpContext context = HttpContext.Current; // Unwrap any TargetInvocationExceptions to get the real exception. e = ExceptionHandlingUtility.GetUnwrappedException(e); // we always send back a 200 (i.e. not re-throwing) with the actual error code in // the results (except fo 404) because silverlight only supports 404/500 error code. If customErrors // are disabled, we'll also send the error message. int errorCode = (int)HttpStatusCode.InternalServerError; if (e is InvalidOperationException) { // invalid operation exception at root level generates BadRequest errorCode = (int)HttpStatusCode.BadRequest; } else if (e is UnauthorizedAccessException) { errorCode = (int)HttpStatusCode.Unauthorized; } else { DomainException dpe = e as DomainException; if (dpe != null) { // we always propagate error info to the client for DomainServiceExceptions fault.ErrorCode = dpe.ErrorCode; fault.ErrorMessage = FormatExceptionMessage(dpe); fault.IsDomainException = true; if (context != null && context.IsCustomErrorEnabled == false) { // also send the stack trace if custom errors is disabled fault.StackTrace = dpe.StackTrace; } return(new FaultException <DomainServiceFault>(fault, new FaultReason(new FaultReasonText(fault.ErrorMessage ?? String.Empty, CultureInfo.CurrentCulture)))); } else { HttpException httpException = e as HttpException; if (httpException != null) { errorCode = httpException.GetHttpCode(); if (errorCode == (int)HttpStatusCode.NotFound) { // for NotFound errors, we don't provide detailed error // info, we just rethrow throw e; } } } } // set error code. Also set error message if custom errors is disabled fault.ErrorCode = errorCode; if (context != null && !context.IsCustomErrorEnabled) { fault.ErrorMessage = FormatExceptionMessage(e); fault.StackTrace = e.StackTrace; } return(new FaultException <DomainServiceFault>(fault, new FaultReason(new FaultReasonText(fault.ErrorMessage ?? String.Empty, CultureInfo.CurrentCulture)))); }
/// <summary> /// Constructs an exception based on a service fault. /// </summary> /// <param name="serviceFault">The fault received from a service.</param> /// <returns>The constructed exception.</returns> private static Exception GetExceptionFromServiceFault(DomainServiceFault serviceFault) { // Status was OK but there still was a server error. We need to transform // the error into the appropriate client exception if (serviceFault.IsDomainException) { return new DomainException(serviceFault.ErrorMessage, serviceFault.ErrorCode, serviceFault.StackTrace); } else if (serviceFault.ErrorCode == 400) { return new DomainOperationException(serviceFault.ErrorMessage, OperationErrorStatus.NotSupported, serviceFault.ErrorCode, serviceFault.StackTrace); } else if (serviceFault.ErrorCode == 401) { return new DomainOperationException(serviceFault.ErrorMessage, OperationErrorStatus.Unauthorized, serviceFault.ErrorCode, serviceFault.StackTrace); } else { // for anything else: map to ServerError return new DomainOperationException(serviceFault.ErrorMessage, OperationErrorStatus.ServerError, serviceFault.ErrorCode, serviceFault.StackTrace); } }