public void CheckErrors_WhenAckCodeIsSuccess_ShouldReturnEmpty(AckCodeType ackCode) { var abstractResponseType = new AbstractResponseType { Ack = ackCode }; var result = _subject.CheckErrors(abstractResponseType); Assert.Equal(string.Empty, result); }
private void AssertCheckoutResponse(AckCodeType codeType, List <ErrorType> errorTypes) { if (codeType.Equals(AckCodeType.FAILURE) || (errorTypes != null && errorTypes.Count > 0)) { var errMsg = string.Join(",", errorTypes.Select(e => e.ShortMessage + ":" + e.ErrorCode)); throw new PayPalDGException(string.Format("An error occurred while processing payment to PayPal. (Error Details: {0})", errMsg)); } }
/// <summary> /// Determines whether [is valid response] [the specified ack code type]. /// </summary> /// <param name="ackCodeType">Type of the ack code.</param> /// <returns> /// <c>true</c> if [is valid response] [the specified ack code type]; otherwise, <c>false</c>. /// </returns> private bool IsValidResponse(AckCodeType ackCodeType) { return ackCodeType != AckCodeType.Success && ackCodeType != AckCodeType.SuccessWithWarning; }
public void CheckErrors_WhenAckCodeIsNotSuccessAndResponseHasNoErrors_ShouldReturnCorrectly(AckCodeType ackCode) { var abstractResponseType = new AbstractResponseType { Ack = ackCode }; var result = _subject.CheckErrors(abstractResponseType); Assert.True(!string.IsNullOrEmpty(result)); }
public void CheckErrors_WhenAckCodeIsNotSuccessAndResponseHasErrors_ShouldReturnCorrectly(AckCodeType ackCode) { var errorCode = "E0001"; var message = "ThisIsVeryLongMessage"; var abstractResponseType = new AbstractResponseType { Ack = ackCode }; abstractResponseType.Errors.Add(new ErrorType { SeverityCode = SeverityCodeType.ERROR, ErrorCode = errorCode, LongMessage = message }); var result = _subject.CheckErrors(abstractResponseType); Assert.Contains(SeverityCodeType.ERROR.ToString(), result); Assert.Contains(errorCode, result); Assert.Contains(message, result); }
/// <summary> /// Writes to response. /// Response headers are customizable by implementing IHasOptions an returning Dictionary of Http headers. /// </summary> /// <param name="response">The response.</param> /// <param name="result">Whether or not it was implicity handled by ServiceStack's built-in handlers.</param> /// <param name="defaultAction">The default action.</param> /// <param name="serializerCtx">The serialization context.</param> /// <param name="bodyPrefix">Add prefix to response body if any</param> /// <param name="bodySuffix">Add suffix to response body if any</param> /// <returns></returns> public static bool WriteToResponse(this IHttpResponse response, IHttpRequest request, object result, ResponseSerializerDelegate defaultAction, IRequestContext serializerCtx, byte[] bodyPrefix, byte[] bodySuffix) { var defaultContentType = serializerCtx.ResponseContentType; AckCodeType ack = AckCodeType.Success; bool completed = true; try { if (result == null) { response.EndRequestWithNoContent(); return true; } ApplyGlobalResponseHeaders(response); /* Mono Error: Exception: Method not found: 'System.Web.HttpResponse.get_Headers' */ var responseOptions = result as IHasOptions; if (responseOptions != null) { //Reserving options with keys in the format 'xx.xxx' (No Http headers contain a '.' so its a safe restriction) const string reservedOptions = "."; foreach (var responseHeaders in responseOptions.Options) { if (responseHeaders.Key.Contains(reservedOptions)) continue; Log.Debug(string.Format("Setting Custom HTTP Header: {0}: {1}", responseHeaders.Key, responseHeaders.Value), new Dictionary<string, string>() { {"ErrorCode", "FXD300061"} }); response.AddHeader(responseHeaders.Key, responseHeaders.Value); } } var disposableResult = result as IDisposable; //ContentType='text/html' is the default for a HttpResponse //Do not override if another has been set if (response.ContentType == null || response.ContentType == ContentType.Html) { response.ContentType = defaultContentType; } if (bodyPrefix != null && response.ContentType.IndexOf(ContentType.Json, StringComparison.InvariantCultureIgnoreCase) >= 0) { response.ContentType = ContentType.JavaScript; } if (EndpointHost.Config.AppendUtf8CharsetOnContentTypes.Contains(response.ContentType)) { response.ContentType += ContentType.Utf8Suffix; } var responseText = result as string; if (responseText != null) { if (bodyPrefix != null) response.OutputStream.Write(bodyPrefix, 0, bodyPrefix.Length); WriteTextToResponse(response, responseText, defaultContentType); if (bodySuffix != null) response.OutputStream.Write(bodySuffix, 0, bodySuffix.Length); return true; } var commonResponseDto = result as IHasResponseStatus; if (commonResponseDto != null) { // defensive programming if (commonResponseDto.ResponseStatus == null) { commonResponseDto.ResponseStatus = new ResponseStatusType(); } commonResponseDto.ResponseStatus.Timestamp = DateTime.Now; // TODO add version // post ack check, in case developer forget to set ack according to error status bool hasError = false; if (commonResponseDto.ResponseStatus.Ack == AckCodeType.Success && commonResponseDto.ResponseStatus.Errors.Count > 0) { foreach (ErrorDataType error in commonResponseDto.ResponseStatus.Errors) { if (error.SeverityCode == SeverityCodeType.Error) { hasError = true; break; } } if (hasError) { commonResponseDto.ResponseStatus.Ack = AckCodeType.Failure; } } ack = commonResponseDto.ResponseStatus.Ack; AddRequestInfoToResponseStatus(serializerCtx.Get<IHttpRequest>(), commonResponseDto); } // Defensive programming, in normal case, we should not see GenericErrorResponseType here // In case any exception, we set http status code to trigger SOA C# client side WebServiceException var genericErrorResponseDto = result as GenericErrorResponseType; if (genericErrorResponseDto != null) { response.StatusCode = (int)HttpStatusCode.InternalServerError; ack = AckCodeType.Failure; } if (defaultAction == null) { throw new ArgumentNullException("defaultAction", String.Format( "As result '{0}' is not a supported responseType, a defaultAction must be supplied", (result != null ? result.GetType().Name : ""))); } if (EndpointHost.Config.ServiceManager.MetadataMap[request.ServicePath].UseChunkedTransferEncoding) { response.AddHeader(ServiceUtils.ResponseStatusHttpHeaderKey, ack.ToString()); response.UseChunkedTransferEncoding(); } if (bodyPrefix != null) response.OutputStream.Write(bodyPrefix, 0, bodyPrefix.Length); if (result != null) { try { defaultAction(serializerCtx, result, response); } catch (Exception) { throw; } finally { //response.SerializationTimeInMillis = serializeTransaction.Transaction.DurationInMillis; } } if (bodySuffix != null) response.OutputStream.Write(bodySuffix, 0, bodySuffix.Length); // Record response size response.ExecutionResult.ResponseSize = response.OutputStream.Length; if (disposableResult != null) disposableResult.Dispose(); return false; } catch (Exception originalEx) { ack = AckCodeType.Failure; bool usedChunkedTransferEncoding = response.UsedChunkedTransferEncoding(); var errorMessage = string.Format("Error occured while {0}: [{1}] {2}", usedChunkedTransferEncoding ? "using chunked transfer encoding" : "processing request", originalEx.GetType().Name, originalEx.Message); Log.Error(errorMessage, originalEx, new Dictionary<string, string>(){ { "ErrorCode", "FXD300010" } }); //TM: It would be good to handle 'remote end dropped connection' problems here. Arguably they should at least be suppressible via configuration //DB: Using standard ServiceStack configuration method if (!EndpointHost.Config.WriteErrorsToResponse) { completed = false; throw; } if (response.IsClosed) return true; if (usedChunkedTransferEncoding) return true; try { response.WriteErrorToResponse(serializerCtx.Get<IHttpRequest>(), defaultContentType, originalEx); return true; } catch (Exception writeErrorEx) { //Exception in writing to response should not hide the original exception Log.Error("Failed to write error to response: " + writeErrorEx.Message, writeErrorEx, new Dictionary<string, string>(){ { "ErrorCode", "FXD300010" } }); completed = false; throw originalEx; } } finally { if (!response.UsedChunkedTransferEncoding()) response.AddHeader(ServiceUtils.ResponseStatusHttpHeaderKey, ack.ToString()); if (completed) response.LogRequest(request); response.EndRequest(true); } }