public void RequestException_RoundTrip_IsIdentical()
        {
            var expected = new RequestException("message").ThrowAndCatch();
            var json     = JsonExceptionSerializer.Serialize(expected);

            var actual = JsonExceptionSerializer.Deserialize(json);

            actual.ShouldBeOfType <RequestException>();
            actual.Message.ShouldBe(expected.Message);
            actual.StackTrace.ShouldBe(expected.StackTrace);
        }
        public void HttpRequestException_RoundTrip_ReturnsSubstitue()
        {
            var ex   = new HttpRequestException("message").ThrowAndCatch();
            var json = JsonExceptionSerializer.Serialize(ex);

            var actual = JsonExceptionSerializer.Deserialize(json);

            var envException = actual.ShouldBeOfType <EnvironmentException>();

            envException.RawMessage().ShouldEndWith(ex.RawMessage());
            envException.UnencryptedTags["originalStackTrace"].ShouldBe(ex.StackTrace);
        }
        public static HttpResponseMessage GetResponseWithException(Exception ex, HttpStatusCode?statusCode = null, bool withGigyaHostHeader = true)
        {
            var resMessage = new HttpResponseMessage {
                StatusCode = statusCode ?? HttpServiceListener.GetExceptionStatusCode(ex)
            };

            if (withGigyaHostHeader)
            {
                resMessage.Headers.Add(GigyaHttpHeaders.ServerHostname, "host");
            }

            resMessage.Content = new StringContent(JsonExceptionSerializer.Serialize(ex));

            return(resMessage);
        }
        public void InnerHttpRequestException_RoundTrip_IsStripped()
        {
            var webEx  = new WebException("Web exception").ThrowAndCatch();
            var httpEx = new HttpRequestException("HTTP request exception", webEx).ThrowAndCatch();
            var ex     = new RemoteServiceException("Remote service exception", "http://foo/bar", httpEx).ThrowAndCatch();

            string json   = JsonExceptionSerializer.Serialize(ex);
            var    actual = JsonExceptionSerializer.Deserialize(json);

            actual.ShouldBeOfType <RemoteServiceException>();
            actual.Message.ShouldBe(ex.Message);
            actual.StackTrace.ShouldBe(ex.StackTrace);
            actual.InnerException.ShouldBeOfType <WebException>();
            actual.InnerException.Message.ShouldBe(webEx.Message);
            actual.InnerException.StackTrace.ShouldBe(webEx.StackTrace);
        }
        public void ExceptionTypeNotAvailable_RoundTrip_FallsBackToAvailableType()
        {
            var expected = new MyException(30000, "message")
            {
                MyNumber = 42
            }.ThrowAndCatch();
            var json = JsonExceptionSerializer.Serialize(expected);

            json = json.Replace("MyException", "MyNonexistentException");
            var actual = (RequestException)JsonExceptionSerializer.Deserialize(json);

            actual.ShouldBeOfType <RequestException>();
            actual.Message.ShouldBe(expected.Message);
            actual.ErrorCode.ShouldBe(30000);
            actual.ExtendedProperties.Count.ShouldBe(1);
            actual.ExtendedProperties.Single().ShouldBe(new KeyValuePair <string, object>("MyNumber", 42L));
            actual.StackTrace.ShouldBe(expected.StackTrace);
        }
        private async Task HandleRequest(HttpListenerContext context)
        {
            RequestTimings.ClearCurrentTimings();
            using (context.Response)
            {
                var sw = Stopwatch.StartNew();

                // Special endpoints should not be logged/measured/traced like regular endpoints
                try
                {
                    foreach (var customEndpoint in CustomEndpoints)
                    {
                        if (await customEndpoint.TryHandle(context, (data, status, type) => TryWriteResponse(context, data, status, type)))
                        {
                            if (RequestTimings.Current.Request.ElapsedMS != null)
                            {
                                _metaEndpointsRoundtripTime.Record((long)RequestTimings.Current.Request.ElapsedMS, TimeUnit.Milliseconds);
                            }
                            return;
                        }
                    }
                }
                catch (Exception e)
                {
                    var ex = GetRelevantException(e);
                    await TryWriteResponse(context, JsonExceptionSerializer.Serialize(ex), GetExceptionStatusCode(ex));

                    return;
                }

                // Regular endpoint handling
                using (_activeRequestsCounter.NewContext("Request"))
                {
                    TracingContext.SetUpStorage();
                    Exception ex;
                    Exception actualException = null;
                    string    methodName      = null;
                    // Initialize with empty object for protocol backwards-compatibility.
                    var requestData = new HttpServiceRequest {
                        TracingData = new TracingData()
                    };

                    ServiceMethod serviceMethod = null;
                    try
                    {
                        try
                        {
                            ValidateRequest(context);
                            await CheckSecureConnection(context);

                            requestData = await ParseRequest(context);

                            TracingContext.SetOverrides(requestData.Overrides);

                            serviceMethod = ServiceEndPointDefinition.Resolve(requestData.Target);
                            methodName    = serviceMethod.ServiceInterfaceMethod.Name;
                        }
                        catch (Exception e)
                        {
                            actualException = e;
                            if (e is RequestException)
                            {
                                throw;
                            }

                            throw new RequestException("Invalid request", e);
                        }

                        var responseJson = await GetResponse(context, serviceMethod, requestData);
                        await TryWriteResponse(context, responseJson);

                        _successCounter.Increment();
                    }
                    catch (Exception e)
                    {
                        actualException = actualException ?? e;
                        _failureCounter.Increment();
                        ex = GetRelevantException(e);

                        string json = _serializationTime.Time(() => JsonExceptionSerializer.Serialize(ex));
                        await TryWriteResponse(context, json, GetExceptionStatusCode(ex));
                    }
                    finally
                    {
                        sw.Stop();
                        _roundtripTime.Record((long)(sw.Elapsed.TotalMilliseconds * 1000000), TimeUnit.Nanoseconds);
                        if (methodName != null)
                        {
                            _endpointContext.Timer(methodName, Unit.Requests).Record((long)(sw.Elapsed.TotalMilliseconds * 1000000), TimeUnit.Nanoseconds);
                        }
                        PublishEvent(requestData, actualException, serviceMethod, sw.Elapsed.TotalMilliseconds);
                    }
                }
            }
        }