public async Task Should_unload_db_and_send_notification_on_catastrophic_failure() { UseNewLocalServer(); using (var store = GetDocumentStore()) { var notifications = new AsyncQueue <DynamicJsonValue>(); using (Server.ServerStore.NotificationCenter.TrackActions(notifications, null)) { var database = await GetDatabase(store.Database); Assert.Equal(1, Server.ServerStore.DatabasesLandlord.DatabasesCache.Count()); try { throw new Exception("Catastrophy"); } catch (Exception e) { database.GetAllStoragesEnvironment().First().Environment.Options.SetCatastrophicFailure(ExceptionDispatchInfo.Capture(e)); } var ex = Assert.Throws <Exception>(() => { using (var context = DocumentsOperationContext.ShortTermSingleUse(database)) { using (var tx = context.OpenWriteTransaction()) { var dynamicJsonValue = new DynamicJsonValue(); using (var doc = context.ReadObject(dynamicJsonValue, "users/1", BlittableJsonDocumentBuilder.UsageMode.ToDisk)) { database.DocumentsStorage.Put(context, "users/1", null, doc); } tx.Commit(); } } }); Assert.Equal("Catastrophy", ex.Message); // db unloaded Assert.True(SpinWait.SpinUntil(() => Server.ServerStore.DatabasesLandlord.DatabasesCache.Any() == false, TimeSpan.FromMinutes(1))); Tuple <bool, DynamicJsonValue> alert; do { alert = await notifications.TryDequeueAsync(TimeSpan.Zero); } while (alert.Item2["Type"].ToString() != NotificationType.AlertRaised.ToString()); Assert.Equal(AlertType.CatastrophicDatabaseFailure, alert.Item2[nameof(AlertRaised.AlertType)]); Assert.Contains(database.Name, alert.Item2[nameof(AlertRaised.Title)] as string); } using (var session = store.OpenSession()) { session.Store(new User()); session.SaveChanges(); } // db loaded again Assert.Equal(1, Server.ServerStore.DatabasesLandlord.DatabasesCache.Count()); } }
// Direct copy of the above RunInternal overload, except that it passes the state into the callback strongly-typed and by ref. internal static void RunInternal <TState>(ExecutionContext executionContext, ContextCallback <TState> callback, ref TState state) { // Note: ExecutionContext.RunInternal is an extremely hot function and used by every await, ThreadPool execution, etc. // Note: Manual enregistering may be addressed by "Exception Handling Write Through Optimization" // https://github.com/dotnet/coreclr/blob/master/Documentation/design-docs/eh-writethru.md // Enregister variables with 0 post-fix so they can be used in registers without EH forcing them to stack // Capture references to Thread Contexts Thread currentThread0 = Thread.CurrentThread; Thread currentThread = currentThread0; ExecutionContext previousExecutionCtx0 = currentThread0.ExecutionContext; if (previousExecutionCtx0 != null && previousExecutionCtx0.m_isDefault) { // Default is a null ExecutionContext internally previousExecutionCtx0 = null; } // Store current ExecutionContext and SynchronizationContext as "previousXxx". // This allows us to restore them and undo any Context changes made in callback.Invoke // so that they won't "leak" back into caller. // These variables will cross EH so be forced to stack ExecutionContext previousExecutionCtx = previousExecutionCtx0; SynchronizationContext previousSyncCtx = currentThread0.SynchronizationContext; if (executionContext != null && executionContext.m_isDefault) { // Default is a null ExecutionContext internally executionContext = null; } if (previousExecutionCtx0 != executionContext) { RestoreChangedContextToThread(currentThread0, executionContext, previousExecutionCtx0); } ExceptionDispatchInfo edi = null; try { callback.Invoke(ref state); } catch (Exception ex) { // Note: we have a "catch" rather than a "finally" because we want // to stop the first pass of EH here. That way we can restore the previous // context before any of our callers' EH filters run. edi = ExceptionDispatchInfo.Capture(ex); } // Re-enregistrer variables post EH with 1 post-fix so they can be used in registers rather than from stack SynchronizationContext previousSyncCtx1 = previousSyncCtx; Thread currentThread1 = currentThread; // The common case is that these have not changed, so avoid the cost of a write barrier if not needed. if (currentThread1.SynchronizationContext != previousSyncCtx1) { // Restore changed SynchronizationContext back to previous currentThread1.SynchronizationContext = previousSyncCtx1; } ExecutionContext previousExecutionCtx1 = previousExecutionCtx; ExecutionContext currentExecutionCtx1 = currentThread1.ExecutionContext; if (currentExecutionCtx1 != previousExecutionCtx1) { RestoreChangedContextToThread(currentThread1, previousExecutionCtx1, currentExecutionCtx1); } // If exception was thrown by callback, rethrow it now original contexts are restored edi?.Throw(); }
protected override async Task <AuthenticationTicket> AuthenticateCoreAsync() { // Allow login to be constrained to a specific path. if (Options.CallbackPath.HasValue && Options.CallbackPath != Request.Path) { return(null); } // assumption: if the ContentType is "application/x-www-form-urlencoded" it should be safe to read as it is small. if (string.Equals(Request.Method, "POST", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(Request.ContentType) // May have media/type; charset=utf-8, allow partial match. && Request.ContentType.StartsWith("application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase) && Request.Body.CanRead) { if (!Request.Body.CanSeek) { // Buffer in case this body was not meant for us. MemoryStream memoryStream = new MemoryStream(); await Request.Body.CopyToAsync(memoryStream); memoryStream.Seek(0, SeekOrigin.Begin); Request.Body = memoryStream; } IFormCollection form = await Request.ReadFormAsync(); // Post preview release: a delegate on WsFederationAuthenticationOptions would allow for users to hook their own custom message. WsFederationMessage wsFederationMessage = new WsFederationMessage(form); if (!wsFederationMessage.IsSignInMessage) { Request.Body.Seek(0, SeekOrigin.Begin); return(null); } MessageReceivedNotification <WsFederationMessage> messageReceivedNotification = null; if (Options.Notifications != null && Options.Notifications.MessageReceived != null) { messageReceivedNotification = new MessageReceivedNotification <WsFederationMessage> { ProtocolMessage = wsFederationMessage }; await Options.Notifications.MessageReceived(messageReceivedNotification); } if (messageReceivedNotification != null && messageReceivedNotification.Cancel) { return(null); } if (wsFederationMessage.Wresult != null) { string token = wsFederationMessage.GetToken(); if (Options.Notifications != null && Options.Notifications.SecurityTokenReceived != null) { SecurityTokenReceivedNotification securityTokenReceivedNotification = new SecurityTokenReceivedNotification { SecurityToken = token }; await Options.Notifications.SecurityTokenReceived(securityTokenReceivedNotification); if (securityTokenReceivedNotification.Cancel) { return(null); } } ExceptionDispatchInfo authFailedEx = null; try { ClaimsPrincipal principal = Options.SecurityTokenHandlers.ValidateToken(token, Options.TokenValidationParameters); ClaimsIdentity claimsIdentity = principal.Identity as ClaimsIdentity; // Retrieve our cached redirect uri string state = wsFederationMessage.Wctx; AuthenticationProperties properties = GetPropertiesFromWctx(state); AuthenticationTicket ticket = new AuthenticationTicket(claimsIdentity, properties); Request.Context.Authentication.SignIn(claimsIdentity); if (Options.Notifications != null && Options.Notifications.SecurityTokenValidated != null) { await Options.Notifications.SecurityTokenValidated(new SecurityTokenValidatedNotification { AuthenticationTicket = ticket }); } return(ticket); } catch (Exception exception) { // We can't await inside a catch block, capture and handle outside. authFailedEx = ExceptionDispatchInfo.Capture(exception); } if (authFailedEx != null) { if (Options.Notifications != null && Options.Notifications.AuthenticationFailed != null) { // Post preview release: user can update metadata, need consistent messaging. var authenticationFailedNotification = new AuthenticationFailedNotification <WsFederationMessage>() { ProtocolMessage = wsFederationMessage, Exception = authFailedEx.SourceException }; await Options.Notifications.AuthenticationFailed(authenticationFailedNotification); if (!authenticationFailedNotification.Cancel) { authFailedEx.Throw(); } } else { authFailedEx.Throw(); } } } } return(null); }
private async Task ProcessAsync(HttpPipelineMessage message, ReadOnlyMemory <HttpPipelinePolicy> pipeline, bool async) { int attempt = 0; List <Exception>?exceptions = null; while (true) { Exception?lastException = null; try { if (async) { await ProcessNextAsync(message, pipeline).ConfigureAwait(false); } else { ProcessNext(message, pipeline); } } catch (Exception ex) { if (exceptions == null) { exceptions = new List <Exception>(); } exceptions.Add(ex); lastException = ex; } TimeSpan delay; attempt++; var shouldRetry = attempt <= _maxRetries; if (lastException != null) { if (shouldRetry && message.ResponseClassifier.IsRetriableException(lastException)) { GetDelay(attempt, out delay); } else { // Rethrow a singular exception if (exceptions?.Count == 1) { ExceptionDispatchInfo.Capture(lastException).Throw(); } throw new AggregateException($"Retry failed after {attempt} tries.", exceptions); } } else if (message.ResponseClassifier.IsErrorResponse(message.Response)) { if (shouldRetry && message.ResponseClassifier.IsRetriableResponse(message.Response)) { GetDelay(message, attempt, out delay); } else { return; } } else { return; } if (delay > TimeSpan.Zero) { if (async) { await WaitAsync(delay, message.CancellationToken).ConfigureAwait(false); } else { Wait(delay, message.CancellationToken); } } HttpPipelineEventSource.Singleton.RequestRetrying(message.Request, attempt); } }
/// <summary>Adds the exception to the fault list.</summary> /// <param name="exceptionObject">The exception to store.</param> /// <remarks> /// Must be called under lock. /// </remarks> private void AddFaultException(object exceptionObject) { Contract.Requires(exceptionObject != null, "AddFaultException(): Expected a non-null exceptionObject"); // Initialize the exceptions list if necessary. The list should be non-null iff it contains exceptions. var exceptions = m_faultExceptions; if (exceptions == null) { m_faultExceptions = exceptions = new List <ExceptionDispatchInfo>(1); } else { Contract.Assert(exceptions.Count > 0, "Expected existing exceptions list to have > 0 exceptions."); } // Handle Exception by capturing it into an ExceptionDispatchInfo and storing that var exception = exceptionObject as Exception; if (exception != null) { exceptions.Add(ExceptionDispatchInfo.Capture(exception)); } else { // Handle ExceptionDispatchInfo by storing it into the list var edi = exceptionObject as ExceptionDispatchInfo; if (edi != null) { exceptions.Add(edi); } else { // Handle enumerables of exceptions by capturing each of the contained exceptions into an EDI and storing it var exColl = exceptionObject as IEnumerable <Exception>; if (exColl != null) { #if DEBUG int numExceptions = 0; #endif foreach (var exc in exColl) { #if DEBUG Contract.Assert(exc != null, "No exceptions should be null"); numExceptions++; #endif exceptions.Add(ExceptionDispatchInfo.Capture(exc)); } #if DEBUG Contract.Assert(numExceptions > 0, "Collection should contain at least one exception."); #endif } else { // Handle enumerables of EDIs by storing them directly var ediColl = exceptionObject as IEnumerable <ExceptionDispatchInfo>; if (ediColl != null) { exceptions.AddRange(ediColl); #if DEBUG Contract.Assert(exceptions.Count > 0, "There should be at least one dispatch info."); foreach (var tmp in exceptions) { Contract.Assert(tmp != null, "No dispatch infos should be null"); } #endif } // Anything else is a programming error else { throw new ArgumentException(Environment.GetResourceString("TaskExceptionHolder_UnknownExceptionType"), "exceptionObject"); } } } } // If all of the exceptions are ThreadAbortExceptions and/or // AppDomainUnloadExceptions, we do not want the finalization // probe to propagate them, so we consider the holder to be // handled. If a subsequent exception comes in of a different // kind, we will reactivate the holder. for (int i = 0; i < exceptions.Count; i++) { var t = exceptions[i].SourceException.GetType(); if (t != typeof(ThreadAbortException) && t != typeof(AppDomainUnloadedException)) { MarkAsUnhandled(); break; } else if (i == exceptions.Count - 1) { MarkAsHandled(false); } } }
internal static InboundFrame ReadFrom(Stream reader, byte[] frameHeaderBuffer) { int type = default; try { type = reader.ReadByte(); } catch (IOException ioe) { // If it's a WSAETIMEDOUT SocketException, unwrap it. // This might happen when the limit of half-open connections is // reached. if (ioe.InnerException is null || !(ioe.InnerException is SocketException exception) || exception.SocketErrorCode != SocketError.TimedOut) { throw; } ExceptionDispatchInfo.Capture(ioe.InnerException).Throw(); } switch (type) { case -1: throw new EndOfStreamException("Reached the end of the stream. Possible authentication failure."); case 'A': // Probably an AMQP protocol header, otherwise meaningless ProcessProtocolHeader(reader); break; } reader.Read(frameHeaderBuffer, 0, frameHeaderBuffer.Length); int channel = NetworkOrderDeserializer.ReadUInt16(new ReadOnlySpan <byte>(frameHeaderBuffer)); int payloadSize = NetworkOrderDeserializer.ReadInt32(new ReadOnlySpan <byte>(frameHeaderBuffer, 2, 4)); // FIXME - throw exn on unreasonable value const int EndMarkerLength = 1; // Is returned by InboundFrame.ReturnPayload in Connection.MainLoopIteration int readSize = payloadSize + EndMarkerLength; byte[] payloadBytes = ArrayPool <byte> .Shared.Rent(readSize); int bytesRead = 0; try { while (bytesRead < readSize) { bytesRead += reader.Read(payloadBytes, bytesRead, readSize - bytesRead); } } catch (Exception) { // Early EOF. ArrayPool <byte> .Shared.Return(payloadBytes); throw new MalformedFrameException($"Short frame - expected to read {readSize} bytes, only got {bytesRead} bytes"); } if (payloadBytes[payloadSize] != Constants.FrameEnd) { ArrayPool <byte> .Shared.Return(payloadBytes); throw new MalformedFrameException($"Bad frame end marker: {payloadBytes[payloadSize]}"); } return(new InboundFrame((FrameType)type, channel, new Memory <byte>(payloadBytes, 0, payloadSize), payloadBytes)); }
/// <nodoc /> public RecoverableExceptionFailure(BuildXLException exception) { Contract.RequiresNotNull(exception); m_exceptionDispatchInfo = ExceptionDispatchInfo.Capture(exception); }
public static void Do <TResult1, TResult2>(RemoteWebDriver browser, Func <IWebElement> webElementSource, Action <Func <IWebElement> > seleniumAction, Func <Func <IWebElement>, TResult1> expectedConditionAfterAction, Func <IWebDriver, TResult2> errorWaitCondition = null, int maxRetries = 10, WaitTime waitTime = WaitTime.Short, [CallerMemberName] string caller = "", StubbornConfiguration configuration = null, string logMessage = null) { configuration = configuration ?? StubbornConfiguration.Default; configuration.Log.Info(logMessage ?? caller); var wait = new WebDriverWait(browser, waitTime.ToTimeSpan()); int attemptNo = 0; while (true) { configuration.BeforeDoActions.ForEach(action => action(browser)); var actionException = Try(() => seleniumAction(webElementSource)); configuration.BetweenDoActions.ForEach(action => action(browser)); var expectedConditionException = Try(() => wait.Until(expectedConditionAfterAction, webElementSource)); if (actionException == null && expectedConditionException == null) { return; } if (attemptNo > 0 && actionException != null && expectedConditionException == null) { configuration.Log.Warning($"Action threw exception (\"{actionException.Message}\") but excepted condition is met"); return; } var relevantException = actionException ?? expectedConditionException; if (attemptNo >= maxRetries) { ExceptionDispatchInfo.Capture(relevantException).Throw(); } attemptNo++; try { if (errorWaitCondition != null) { wait.Until(errorWaitCondition); } else { Thread.Sleep(WaitTime.Short.ToTimeSpan()); } } catch (Exception) { // Ignore wait errors - just try to perform the core action again } configuration.Log.Warning($"Repeating {caller}"); } }
/// <summary> /// Searches the 'Authorization' header for a 'Bearer' token. If the 'Bearer' token is found, it is validated using <see cref="T:Microsoft.IdentityModel.Tokens.TokenValidationParameters" /> set in the options. /// </summary> /// <returns></returns> protected override async Task <AuthenticateResult> HandleAuthenticateAsync() { string token; Exception obj; AuthenticationFailedContext authenticationFailedContext; int num; try { var messageReceivedContext = new MessageReceivedContext(Context, Scheme, Options); await Events.MessageReceived(messageReceivedContext); if (messageReceivedContext.Result != null) { return(messageReceivedContext.Result); } token = messageReceivedContext.Token; if (string.IsNullOrEmpty(token)) { string header = Request.Headers["Authorization"]; if (string.IsNullOrEmpty(header)) { return(AuthenticateResult.NoResult()); } if (header.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)) { token = header.Substring("Bearer ".Length).Trim(); } if (string.IsNullOrEmpty(token)) { return(AuthenticateResult.NoResult()); } } if (_configuration == null && Options.ConfigurationManager != null) { var configurationAsync = await Options.ConfigurationManager.GetConfigurationAsync(Context.RequestAborted); _configuration = configurationAsync; } var validationParameters1 = Options.TokenValidationParameters.Clone(); if (_configuration != null) { var strArray = new string[1] { _configuration.Issuer }; var validationParameters2 = validationParameters1; var validIssuers = validationParameters1.ValidIssuers; var obj1 = (validIssuers != null ? validIssuers.Concat(strArray) : null) ?? strArray; validationParameters2.ValidIssuers = obj1; var validationParameters3 = validationParameters1; var issuerSigningKeys = validationParameters1.IssuerSigningKeys; var securityKeys = (issuerSigningKeys != null ? issuerSigningKeys.Concat(_configuration.SigningKeys) : null) ?? _configuration.SigningKeys; validationParameters3.IssuerSigningKeys = securityKeys; } List <Exception> exceptionList = null; foreach (var securityTokenValidator in Options.SecurityTokenValidators) { if (securityTokenValidator.CanReadToken(token)) { SecurityToken securityToken; ClaimsPrincipal claimsPrincipal; try { claimsPrincipal = securityTokenValidator.ValidateToken(token, validationParameters1, out securityToken); } catch (Exception ex) { //Logger.TokenValidationFailed(ex); if (Options.RefreshOnIssuerKeyNotFound && Options.ConfigurationManager != null && ex is SecurityTokenSignatureKeyNotFoundException) { Options.ConfigurationManager.RequestRefresh(); } if (exceptionList == null) { exceptionList = new List <Exception>(1); } exceptionList.Add(ex); continue; } //Logger.TokenValidationSucceeded(); var validatedContext = new TokenValidatedContext(Context, Scheme, Options); validatedContext.Principal = claimsPrincipal; validatedContext.SecurityToken = securityToken; var tokenValidatedContext = validatedContext; await Events.TokenValidated(tokenValidatedContext); if (tokenValidatedContext.Result != null) { return(tokenValidatedContext.Result); } if (Options.SaveToken) { tokenValidatedContext.Properties.StoreTokens(new AuthenticationToken[1] { new AuthenticationToken() { Name = "access_token", Value = token } }); } tokenValidatedContext.Success(); return(tokenValidatedContext.Result); } } if (exceptionList == null) { return(AuthenticateResult.Fail("No SecurityTokenValidator available for token: " + token ?? "[null]")); } authenticationFailedContext = new AuthenticationFailedContext(Context, Scheme, Options) { Exception = exceptionList.Count == 1 ? exceptionList[0] : new AggregateException(exceptionList) }; await Events.AuthenticationFailed(authenticationFailedContext); return(authenticationFailedContext.Result == null?AuthenticateResult.Fail(authenticationFailedContext.Exception) : authenticationFailedContext.Result); } catch (Exception ex) { obj = ex; num = 1; } if (num == 1) { var ex = obj; //Logger.ErrorProcessingMessage(ex); authenticationFailedContext = new AuthenticationFailedContext(Context, Scheme, Options) { Exception = ex }; await Events.AuthenticationFailed(authenticationFailedContext); if (authenticationFailedContext.Result != null) { return(authenticationFailedContext.Result); } var source = obj as Exception; if (source == null) { throw obj; } ExceptionDispatchInfo.Capture(source).Throw(); authenticationFailedContext = null; } return(null); }
/// <summary> /// /// </summary> /// <param name="messages"></param> /// <param name="timeout"></param> /// <param name="cancellationToken"></param> /// <returns></returns> internal async Task <long[]> ScheduleMessageInternalAsync( IList <ServiceBusMessage> messages, TimeSpan timeout, CancellationToken cancellationToken = default) { var sendLink = default(SendingAmqpLink); try { var request = AmqpRequestMessage.CreateRequest( ManagementConstants.Operations.ScheduleMessageOperation, timeout, null); if (_sendLink.TryGetOpenedObject(out sendLink)) { request.AmqpMessage.ApplicationProperties.Map[ManagementConstants.Request.AssociatedLinkName] = sendLink.Name; } List <AmqpMap> entries = new List <AmqpMap>(); foreach (ServiceBusMessage message in messages) { using AmqpMessage amqpMessage = AmqpMessageConverter.SBMessageToAmqpMessage(message); var entry = new AmqpMap(); ArraySegment <byte>[] payload = amqpMessage.GetPayload(); var buffer = new BufferListStream(payload); ArraySegment <byte> value = buffer.ReadBytes((int)buffer.Length); entry[ManagementConstants.Properties.Message] = value; entry[ManagementConstants.Properties.MessageId] = message.MessageId; if (!string.IsNullOrWhiteSpace(message.SessionId)) { entry[ManagementConstants.Properties.SessionId] = message.SessionId; } if (!string.IsNullOrWhiteSpace(message.PartitionKey)) { entry[ManagementConstants.Properties.PartitionKey] = message.PartitionKey; } if (!string.IsNullOrWhiteSpace(message.ViaPartitionKey)) { entry[ManagementConstants.Properties.ViaPartitionKey] = message.ViaPartitionKey; } entries.Add(entry); } request.Map[ManagementConstants.Properties.Messages] = entries; AmqpResponseMessage amqpResponseMessage = await ManagementUtilities.ExecuteRequestResponseAsync( _connectionScope, _managementLink, request, timeout).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); if (amqpResponseMessage.StatusCode == AmqpResponseStatusCode.OK) { var sequenceNumbers = amqpResponseMessage.GetValue <long[]>(ManagementConstants.Properties.SequenceNumbers); if (sequenceNumbers == null || sequenceNumbers.Length < 1) { throw new ServiceBusException(true, "Could not schedule message successfully."); } return(sequenceNumbers); } else { throw amqpResponseMessage.ToMessagingContractException(); } } catch (Exception exception) { ExceptionDispatchInfo.Capture(AmqpExceptionHelper.TranslateException( exception, sendLink?.GetTrackingId(), null, HasLinkCommunicationError(sendLink))) .Throw(); throw; // will never be reached } }
internal void ValidateCreateContext( string package, bool isServer, NetworkCredential credential, string servicePrincipalName, ChannelBinding channelBinding, ProtectionLevel protectionLevel, TokenImpersonationLevel impersonationLevel) { if (_exception != null && !_canRetryAuthentication) { ExceptionDispatchInfo.Capture(_exception).Throw(); } if (_context != null && _context.IsValidContext) { throw new InvalidOperationException(SR.net_auth_reauth); } if (credential == null) { throw new ArgumentNullException(nameof(credential)); } if (servicePrincipalName == null) { throw new ArgumentNullException(nameof(servicePrincipalName)); } NegotiateStreamPal.ValidateImpersonationLevel(impersonationLevel); if (_context != null && IsServer != isServer) { throw new InvalidOperationException(SR.net_auth_client_server); } _exception = null; _remoteOk = false; _framer = new StreamFramer(_innerStream); _framer.WriteHeader.MessageId = FrameHeader.HandshakeId; _expectedProtectionLevel = protectionLevel; _expectedImpersonationLevel = isServer ? impersonationLevel : TokenImpersonationLevel.None; _writeSequenceNumber = 0; _readSequenceNumber = 0; ContextFlagsPal flags = ContextFlagsPal.Connection; // A workaround for the client when talking to Win9x on the server side. if (protectionLevel == ProtectionLevel.None && !isServer) { package = NegotiationInfoClass.NTLM; } else if (protectionLevel == ProtectionLevel.EncryptAndSign) { flags |= ContextFlagsPal.Confidentiality; } else if (protectionLevel == ProtectionLevel.Sign) { // Assuming user expects NT4 SP4 and above. flags |= (ContextFlagsPal.ReplayDetect | ContextFlagsPal.SequenceDetect | ContextFlagsPal.InitIntegrity); } if (isServer) { if (_extendedProtectionPolicy.PolicyEnforcement == PolicyEnforcement.WhenSupported) { flags |= ContextFlagsPal.AllowMissingBindings; } if (_extendedProtectionPolicy.PolicyEnforcement != PolicyEnforcement.Never && _extendedProtectionPolicy.ProtectionScenario == ProtectionScenario.TrustedProxy) { flags |= ContextFlagsPal.ProxyBindings; } } else { // Server side should not request any of these flags. if (protectionLevel != ProtectionLevel.None) { flags |= ContextFlagsPal.MutualAuth; } if (impersonationLevel == TokenImpersonationLevel.Identification) { flags |= ContextFlagsPal.InitIdentify; } if (impersonationLevel == TokenImpersonationLevel.Delegation) { flags |= ContextFlagsPal.Delegate; } } _canRetryAuthentication = false; try { _context = new NTAuthentication(isServer, package, credential, servicePrincipalName, flags, channelBinding); } catch (Win32Exception e) { throw new AuthenticationException(SR.net_auth_SSPI, e); } }
/// <summary> /// Sends a set of messages to the associated Queue/Topic using a batched approach. /// </summary> /// /// <param name="messageFactory"></param> /// <param name="timeout"></param> /// <param name="cancellationToken">An optional <see cref="CancellationToken"/> instance to signal the request to cancel the operation.</param> /// internal virtual async Task SendBatchInternalAsync( Func <AmqpMessage> messageFactory, TimeSpan timeout, CancellationToken cancellationToken) { var stopWatch = ValueStopwatch.StartNew(); var link = default(SendingAmqpLink); try { using (AmqpMessage batchMessage = messageFactory()) { string messageHash = batchMessage.GetHashCode().ToString(CultureInfo.InvariantCulture); ArraySegment <byte> transactionId = AmqpConstants.NullBinary; Transaction ambientTransaction = Transaction.Current; if (ambientTransaction != null) { transactionId = await AmqpTransactionManager.Instance.EnlistAsync( ambientTransaction, _connectionScope, timeout).ConfigureAwait(false); } link = await _sendLink.GetOrCreateAsync(UseMinimum(_connectionScope.SessionTimeout, timeout)).ConfigureAwait(false); // Validate that the message is not too large to send. This is done after the link is created to ensure // that the maximum message size is known, as it is dictated by the service using the link. if (batchMessage.SerializedMessageSize > MaxMessageSize) { throw new ServiceBusException(string.Format(CultureInfo.InvariantCulture, Resources.MessageSizeExceeded, messageHash, batchMessage.SerializedMessageSize, MaxMessageSize, _entityPath), ServiceBusFailureReason.MessageSizeExceeded); } // Attempt to send the message batch. var deliveryTag = new ArraySegment <byte>(BitConverter.GetBytes(Interlocked.Increment(ref _deliveryCount))); Outcome outcome = await link.SendMessageAsync( batchMessage, deliveryTag, transactionId, timeout.CalculateRemaining(stopWatch.GetElapsedTime())).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); if (outcome.DescriptorCode != Accepted.Code) { throw (outcome as Rejected)?.Error.ToMessagingContractException(); } cancellationToken.ThrowIfCancellationRequested <TaskCanceledException>(); } } catch (Exception exception) { ExceptionDispatchInfo.Capture(AmqpExceptionHelper.TranslateException( exception, link?.GetTrackingId(), null, HasLinkCommunicationError(link))) .Throw(); throw; // will never be reached } }
public void ReportError(Parser recognizer, RecognitionException e) { ExceptionDispatchInfo.Capture(e).Throw(); }
/// <inheritdoc /> public Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) { throw new ArgumentNullException(nameof(bindingContext)); } _logger.AttemptingToBindModel(bindingContext); var modelName = bindingContext.ModelName; var valueProviderResult = bindingContext.ValueProvider.GetValue(modelName); if (valueProviderResult == ValueProviderResult.None) { _logger.FoundNoValueInRequest(bindingContext); // no entry _logger.DoneAttemptingToBindModel(bindingContext); return(Task.CompletedTask); } var modelState = bindingContext.ModelState; modelState.SetModelValue(modelName, valueProviderResult); var metadata = bindingContext.ModelMetadata; var type = metadata.UnderlyingOrModelType; try { var value = valueProviderResult.FirstValue; object model; if (string.IsNullOrWhiteSpace(value)) { // Parse() method trims the value (with common NumberStyles) then throws if the result is empty. model = null; } else if (type == typeof(decimal)) { model = decimal.Parse(value, _supportedStyles, valueProviderResult.Culture); } else { // unreachable throw new NotSupportedException(); } // When converting value, a null model may indicate a failed conversion for an otherwise required // model (can't set a ValueType to null). This detects if a null model value is acceptable given the // current bindingContext. If not, an error is logged. if (model == null && !metadata.IsReferenceOrNullableType) { modelState.TryAddModelError( modelName, metadata.ModelBindingMessageProvider.ValueMustNotBeNullAccessor( valueProviderResult.ToString())); } else { bindingContext.Result = ModelBindingResult.Success(model); } } catch (Exception exception) { var isFormatException = exception is FormatException; if (!isFormatException && exception.InnerException != null) { // Unlike TypeConverters, floating point types do not seem to wrap FormatExceptions. Preserve // this code in case a cursory review of the CoreFx code missed something. exception = ExceptionDispatchInfo.Capture(exception.InnerException).SourceException; } modelState.TryAddModelError(modelName, exception, metadata); // Conversion failed. } _logger.DoneAttemptingToBindModel(bindingContext); return(Task.CompletedTask); }
/// <summary> /// Rethrows an exception without losing stack information. /// </summary> /// <param name="ex"></param> /// <remarks> /// Copied from http://stackoverflow.com/questions/4555599/how-to-rethrow-the-inner-exception-of-a-targetinvocationexception-without-losing. /// </remarks> public static void Rethrow(Exception ex) { var exceptionDispatchInfo = ExceptionDispatchInfo.Capture(ex); exceptionDispatchInfo.Throw(); }
/// <summary>Adds the exception to the fault list.</summary> /// <param name="exceptionObject">The exception to store.</param> /// <remarks> /// Must be called under lock. /// </remarks> private void AddFaultException(object exceptionObject) { Contract.Requires(exceptionObject != null, "AddFaultException(): Expected a non-null exceptionObject"); // Initialize the exceptions list if necessary. The list should be non-null iff it contains exceptions. var exceptions = m_faultExceptions; if (exceptions == null) { m_faultExceptions = exceptions = new List <ExceptionDispatchInfo>(1); } else { Contract.Assert(exceptions.Count > 0, "Expected existing exceptions list to have > 0 exceptions."); } // Handle Exception by capturing it into an ExceptionDispatchInfo and storing that var exception = exceptionObject as Exception; if (exception != null) { exceptions.Add(ExceptionDispatchInfo.Capture(exception)); } else { // Handle ExceptionDispatchInfo by storing it into the list var edi = exceptionObject as ExceptionDispatchInfo; if (edi != null) { exceptions.Add(edi); } else { // Handle enumerables of exceptions by capturing each of the contained exceptions into an EDI and storing it var exColl = exceptionObject as IEnumerable <Exception>; if (exColl != null) { #if DEBUG int numExceptions = 0; #endif foreach (var exc in exColl) { #if DEBUG Contract.Assert(exc != null, "No exceptions should be null"); numExceptions++; #endif exceptions.Add(ExceptionDispatchInfo.Capture(exc)); } #if DEBUG Contract.Assert(numExceptions > 0, "Collection should contain at least one exception."); #endif } else { // Handle enumerables of EDIs by storing them directly var ediColl = exceptionObject as IEnumerable <ExceptionDispatchInfo>; if (ediColl != null) { exceptions.AddRange(ediColl); #if DEBUG Contract.Assert(exceptions.Count > 0, "There should be at least one dispatch info."); foreach (var tmp in exceptions) { Contract.Assert(tmp != null, "No dispatch infos should be null"); } #endif } // Anything else is a programming error else { throw new ArgumentException(SR.TaskExceptionHolder_UnknownExceptionType, "exceptionObject"); } } } } if (exceptions.Count > 0) { MarkAsUnhandled(); } }
/// <summary> /// B層の一般的な例外による異常終了の後処理を実装するUOCメソッド。 /// </summary> /// <param name="parameterValue">引数クラス</param> /// <param name="returnValue">戻り値クラス</param> /// <param name="ex">Exception</param> /// <remarks>業務コード親クラス1から利用される派生の末端</remarks> protected override void UOC_ABEND(BaseParameterValue parameterValue, ref BaseReturnValue returnValue, Exception ex) { // 一般的な例外発生時の処理を実装 // TODO: // nullチェック if (this.perfRec == null) { // なにもしない // スタックトレースを保って InnerException を throw ExceptionDispatchInfo.Capture(ex).Throw(); } else { // 性能測定終了 this.perfRec.EndsPerformanceRecord(); // キャスト MyParameterValue myPV = (MyParameterValue)parameterValue; // システム例外に振り替える用のワーク bool sysErrorFlag = false; string sysErrorMessageID = ""; string sysErrorMessage = ""; #region 例外の振替処理のIF文 if (ex.Message == "Other-Business") { // 業務例外へ変換 returnValue.ErrorFlag = true; returnValue.ErrorMessageID = "振替後"; returnValue.ErrorMessage = "振替後"; returnValue.ErrorInfo = "振り替える場合は、基本的にここを利用。"; } else if (ex.Message == "Other-System") { // システム例外へ振替 sysErrorFlag = true; sysErrorMessageID = "振替後"; sysErrorMessage = "振替後"; } #endregion #region ACCESSログ出力、リスローする・しない if (returnValue.ErrorFlag) { // 業務例外へ変換 // ------------ // メッセージ部 // ------------ // ユーザ名, IPアドレス, レイヤ, // 画面名, コントロール名, メソッド名, 処理名 // 処理時間(実行時間), 処理時間(CPU時間) // エラーメッセージID, エラーメッセージ等 // ------------ string strLogMessage = "," + myPV.User.UserName + "," + myPV.User.IPAddress + "," + "<<-----" + "," + myPV.ScreenId + "," + myPV.ControlId + "," + myPV.MethodName + "," + myPV.ActionType + "," + this.perfRec.ExecTime + "," + this.perfRec.CpuTime + "," + returnValue.ErrorMessageID + "," + returnValue.ErrorMessage; // baEX // Log4Netへログ出力 LogIF.WarnLog("ACCESS", strLogMessage); } else if (sysErrorFlag) { // システム例外へ振替 // ------------ // メッセージ部 // ------------ // ユーザ名, IPアドレス, レイヤ, // 画面名, コントロール名, メソッド名, 処理名 // 処理時間(実行時間), 処理時間(CPU時間) // エラーメッセージID, エラーメッセージ等 // ------------ string strLogMessage = "," + myPV.User.UserName + "," + myPV.User.IPAddress + "," + "<<-----" + "," + myPV.ScreenId + "," + myPV.ControlId + "," + myPV.MethodName + "," + myPV.ActionType + "," + this.perfRec.ExecTime + "," + this.perfRec.CpuTime + "," + sysErrorMessageID + "," + sysErrorMessage + "\r\n" + ex.StackTrace; // bsEX // Log4Netへログ出力 LogIF.ErrorLog("ACCESS", strLogMessage); // 振替てスロー throw new BusinessSystemException(sysErrorMessageID, sysErrorMessage); } else { // そのまま // ------------ // メッセージ部 // ------------ // ユーザ名, IPアドレス, レイヤ, // 画面名, コントロール名, メソッド名, 処理名 // 処理時間(実行時間), 処理時間(CPU時間) // エラーメッセージID, エラーメッセージ等 // ------------ string strLogMessage = "," + myPV.User.UserName + "," + myPV.User.IPAddress + "," + "<<-----" + "," + myPV.ScreenId + "," + myPV.ControlId + "," + myPV.MethodName + "," + myPV.ActionType + "," + this.perfRec.ExecTime + "," + this.perfRec.CpuTime + "," + "other Exception" + "," + ex.Message + "\r\n" + ex.ToString(); // ex // Log4Netへログ出力 LogIF.ErrorLog("ACCESS", strLogMessage); // スタックトレースを保って InnerException を throw ExceptionDispatchInfo.Capture(ex).Throw(); } #endregion } }
public static void Execute(StorageEnvironmentOptions srcOptions, StorageEnvironmentOptions.DirectoryStorageEnvironmentOptions compactOptions, Action <StorageCompactionProgress> progressReport = null, CancellationToken token = default(CancellationToken)) { if (srcOptions.IncrementalBackupEnabled) { throw new InvalidOperationException(CannotCompactBecauseOfIncrementalBackup); } long minimalCompactedDataFileSize; srcOptions.ManualFlushing = true; // prevent from flushing during compaction - we shouldn't touch any source files compactOptions.ManualFlushing = true; // let us flush manually during data copy using (var existingEnv = new StorageEnvironment(srcOptions)) using (var compactedEnv = new StorageEnvironment(compactOptions)) { CopyTrees(existingEnv, compactedEnv, progressReport, token); compactedEnv.FlushLogToDataFile(); bool synced; const int maxNumberOfRetries = 100; var syncRetries = 0; while (true) { token.ThrowIfCancellationRequested(); using (var op = new WriteAheadJournal.JournalApplicator.SyncOperation(compactedEnv.Journal.Applicator)) { try { synced = op.SyncDataFile(); if (synced || ++syncRetries >= maxNumberOfRetries) { break; } Thread.Sleep(100); } catch (Exception e) { existingEnv.Options.SetCatastrophicFailure(ExceptionDispatchInfo.Capture(e)); throw; } } } if (synced) { compactedEnv.Journal.Applicator.DeleteCurrentAlreadyFlushedJournal(); } compactedEnv.Cleanup(); minimalCompactedDataFileSize = compactedEnv.NextPageNumber * Constants.Storage.PageSize; } using (var compactedDataFile = SafeFileStream.Create(compactOptions.BasePath.Combine(Constants.DatabaseFilename).FullPath, FileMode.Open, FileAccess.ReadWrite)) { compactedDataFile.SetLength(minimalCompactedDataFileSize); } }
public static void RunGameTest(GameBase game) { // Prepare finish callback var tcs = new TaskCompletionSource <bool>(); EventHandler <EventArgs> gameFinishedCallback = (sender, e) => { // Notify waiter that game has exited Logger.Info("Game finished."); tcs.TrySetResult(true); }; EventHandler <GameUnhandledExceptionEventArgs> exceptionhandler = (sender, e) => { Logger.Info("Game finished with exception ={0}.", e); tcs.TrySetException((Exception)e.ExceptionObject); }; // Transmit data to activity // TODO: Avoid static with string intent + Dictionary? try { game.UnhandledException += exceptionhandler; Logger.Info(@"Starting activity"); #if SILICONSTUDIO_PLATFORM_IOS game.Exiting += gameFinishedCallback; UIApplication.SharedApplication.InvokeOnMainThread(() => { var window = UIApplication.SharedApplication.KeyWindow; var rootNavigationController = (UINavigationController)window.RootViewController; // create the paradox game view var bounds = UIScreen.MainScreen.Bounds; var paradoxGameView = new Starter.ParadoxApplicationDelegate.iOSParadoxView((System.Drawing.RectangleF)bounds) { ContentScaleFactor = UIScreen.MainScreen.Scale }; // create the view controller used to display the paradox game var paradoxGameController = new iOSGameTestController(game) { View = paradoxGameView }; // create the game context var gameContext = new GameContext(window, paradoxGameView, paradoxGameController); // push view rootNavigationController.PushViewController(gameContext.GameViewController, false); // launch the game game.Run(gameContext); }); #elif SILICONSTUDIO_PLATFORM_ANDROID // Start activity AndroidGameTestActivity.Game = game; AndroidGameTestActivity.Destroyed += gameFinishedCallback; PlatformAndroid.Context.StartActivity(typeof(AndroidGameTestActivity)); #endif // Wait for completion of task // TODO: Should we put a timeout and issue a Game.Exit() in main thread if too long? tcs.Task.Wait(); Logger.Info(@"Activity ended"); } catch (AggregateException e) { // Unwrap aggregate exceptions if (e.InnerExceptions.Count == 1) { ExceptionDispatchInfo.Capture(e.InnerException).Throw(); } } finally { #if SILICONSTUDIO_PLATFORM_IOS // iOS Cleanup UIApplication.SharedApplication.InvokeOnMainThread(() => { var window = UIApplication.SharedApplication.KeyWindow; var rootNavigationController = (UINavigationController)window.RootViewController; rootNavigationController.PopViewController(false); }); #elif SILICONSTUDIO_PLATFORM_ANDROID AndroidGameTestActivity.Game = null; AndroidGameTestActivity.Destroyed -= gameFinishedCallback; #endif // Cleanup game.Exiting -= gameFinishedCallback; game.UnhandledException -= exceptionhandler; } }
/// <summary> /// Handles ClientRequestServer messages. /// It will try to find a matching service (spawn it if not started yet), and ask it to establish a new "server" connection back to us. /// </summary> /// <param name="clientSocket">The client socket context.</param> /// <returns></returns> private async Task HandleMessageClientRequestServer(SimpleSocket clientSocket) { // Check for an existing server // TODO: Proper Url parsing (query string) var url = await clientSocket.ReadStream.ReadStringAsync(); Log.Info($"Client {clientSocket.RemoteAddress}:{clientSocket.RemotePort} sent message ClientRequestServer with URL {url}"); string[] urlSegments; string urlParameters; RouterHelper.ParseUrl(url, out urlSegments, out urlParameters); if (urlSegments.Length == 0) { throw new InvalidOperationException("No URL Segments"); } SimpleSocket serverSocket = null; ExceptionDispatchInfo serverSocketCapturedException = null; try { // For now, we handle only "service" URL switch (urlSegments[0]) { case "service": { // From the URL, start service (if not started yet) and ask it to provide a server serverSocket = await SpawnServerFromService(url, false); break; } case "task": { // From the URL, start service (if not started yet) and ask it to provide a server serverSocket = await SpawnServerFromService(url, true); } break; case "redirect": { // Redirect to a IP/port serverSocket = new SimpleSocket(); var host = urlSegments[1]; var port = int.Parse(urlSegments[2]); // Note: for security reasons, we currently use a whitelist //if (host == "xenkobuild.xenko.com" && port == 1832) // await serverSocket.StartClient(host, port, false); //else throw new InvalidOperationException("Trying to redirect to a non-whitelisted host/port"); break; } default: throw new InvalidOperationException("This type of URL is not supported"); } } catch (Exception e) { serverSocketCapturedException = ExceptionDispatchInfo.Capture(e); } if (serverSocketCapturedException != null) { try { // Notify client that there was an error await clientSocket.WriteStream.WriteInt16Async((short)RouterMessage.ClientServerStarted); await clientSocket.WriteStream.WriteInt32Async(1); // error code Failure await clientSocket.WriteStream.WriteStringAsync(serverSocketCapturedException.SourceException.Message); await clientSocket.WriteStream.FlushAsync(); } finally { serverSocketCapturedException.Throw(); } } try { // Notify client that we've found a server for it await clientSocket.WriteStream.WriteInt16Async((short)RouterMessage.ClientServerStarted); await clientSocket.WriteStream.WriteInt32Async(0); // error code OK await clientSocket.WriteStream.FlushAsync(); // Let's forward clientSocketContext and serverSocketContext await await Task.WhenAny( ForwardSocket(clientSocket, serverSocket), ForwardSocket(serverSocket, clientSocket)); } catch { serverSocket.Dispose(); throw; } }
public static void RethrowToKeepStackTrace(this Exception ex) { ExceptionDispatchInfo.Capture(ex).Throw(); }
/// <summary> /// If instances of the underlying <see cref="DbContext" /> type can be created, returns /// a new instance; otherwise returns null. /// </summary> /// <returns> /// A <see cref="DbContext" /> instance. /// </returns> public virtual DbContext CreateInstance() { var configPushed = DbConfigurationManager.Instance.PushConfiguration(_appConfig, _contextType); CurrentInfo = this; DbContext context = null; try { try { context = _activator == null ? null : _activator(); } catch (TargetInvocationException ex) { Debug.Assert(ex.InnerException != null); #if !NET40 ExceptionDispatchInfo.Capture(ex.InnerException).Throw(); #endif throw ex.InnerException; } if (context == null) { return(null); } context.InternalContext.OnDisposing += (_, __) => CurrentInfo = null; if (configPushed) { context.InternalContext.OnDisposing += (_, __) => DbConfigurationManager.Instance.PopConfiguration(_appConfig); } context.InternalContext.ApplyContextInfo(this); return(context); } catch (Exception) { if (context != null) { context.Dispose(); } throw; } finally { if (context == null) { CurrentInfo = null; if (configPushed) { DbConfigurationManager.Instance.PopConfiguration(_appConfig); } } } }
public void SetException(Exception error) { _error = ExceptionDispatchInfo.Capture(error); SignalCompletion(); }
private HubMessage ParseMessage(Utf8BufferTextReader textReader, IInvocationBinder binder) { try { // We parse using the JsonTextReader directly but this has a problem. Some of our properties are dependent on other properties // and since reading the json might be unordered, we need to store the parsed content as JToken to re-parse when true types are known. // if we're lucky and the state we need to directly parse is available, then we'll use it. int? type = null; string invocationId = null; string streamId = null; string target = null; string error = null; var hasItem = false; object item = null; JToken itemToken = null; var hasResult = false; object result = null; JToken resultToken = null; var hasArguments = false; object[] arguments = null; JArray argumentsToken = null; ExceptionDispatchInfo argumentBindingException = null; Dictionary <string, string> headers = null; var completed = false; using (var reader = JsonUtils.CreateJsonTextReader(textReader)) { reader.DateParseHandling = DateParseHandling.None; JsonUtils.CheckRead(reader); // We're always parsing a JSON object JsonUtils.EnsureObjectStart(reader); do { switch (reader.TokenType) { case JsonToken.PropertyName: var memberName = reader.Value.ToString(); switch (memberName) { case TypePropertyName: var messageType = JsonUtils.ReadAsInt32(reader, TypePropertyName); if (messageType == null) { throw new InvalidDataException($"Missing required property '{TypePropertyName}'."); } type = messageType.Value; break; case InvocationIdPropertyName: invocationId = JsonUtils.ReadAsString(reader, InvocationIdPropertyName); break; case StreamIdPropertyName: streamId = JsonUtils.ReadAsString(reader, StreamIdPropertyName); break; case TargetPropertyName: target = JsonUtils.ReadAsString(reader, TargetPropertyName); break; case ErrorPropertyName: error = JsonUtils.ReadAsString(reader, ErrorPropertyName); break; case ResultPropertyName: hasResult = true; if (string.IsNullOrEmpty(invocationId)) { JsonUtils.CheckRead(reader); // If we don't have an invocation id then we need to store it as a JToken so we can parse it later resultToken = JToken.Load(reader); } else { // If we have an invocation id already we can parse the end result var returnType = binder.GetReturnType(invocationId); if (!JsonUtils.ReadForType(reader, returnType)) { throw new JsonReaderException("Unexpected end when reading JSON"); } result = PayloadSerializer.Deserialize(reader, returnType); } break; case ItemPropertyName: JsonUtils.CheckRead(reader); hasItem = true; string id = null; if (!string.IsNullOrEmpty(invocationId)) { id = invocationId; } else if (!string.IsNullOrEmpty(streamId)) { id = streamId; } else { // If we don't have an id yetmthen we need to store it as a JToken to parse later itemToken = JToken.Load(reader); break; } Type itemType = binder.GetStreamItemType(id); try { item = PayloadSerializer.Deserialize(reader, itemType); } catch (JsonSerializationException ex) { return(new StreamBindingFailureMessage(id, ExceptionDispatchInfo.Capture(ex))); } break; case ArgumentsPropertyName: JsonUtils.CheckRead(reader); int initialDepth = reader.Depth; if (reader.TokenType != JsonToken.StartArray) { throw new InvalidDataException($"Expected '{ArgumentsPropertyName}' to be of type {JTokenType.Array}."); } hasArguments = true; if (string.IsNullOrEmpty(target)) { // We don't know the method name yet so just parse an array of generic JArray argumentsToken = JArray.Load(reader); } else { try { var paramTypes = binder.GetParameterTypes(target); arguments = BindArguments(reader, paramTypes); } catch (Exception ex) { argumentBindingException = ExceptionDispatchInfo.Capture(ex); // Could be at any point in argument array JSON when an error is thrown // Read until the end of the argument JSON array while (reader.Depth == initialDepth && reader.TokenType == JsonToken.StartArray || reader.Depth > initialDepth) { JsonUtils.CheckRead(reader); } } } break; case HeadersPropertyName: JsonUtils.CheckRead(reader); headers = ReadHeaders(reader); break; default: // Skip read the property name JsonUtils.CheckRead(reader); // Skip the value for this property reader.Skip(); break; } break; case JsonToken.EndObject: completed = true; break; } }while (!completed && JsonUtils.CheckRead(reader)); } HubMessage message; switch (type) { case HubProtocolConstants.InvocationMessageType: { if (argumentsToken != null) { // We weren't able to bind the arguments because they came before the 'target', so try to bind now that we've read everything. try { var paramTypes = binder.GetParameterTypes(target); arguments = BindArguments(argumentsToken, paramTypes); } catch (Exception ex) { argumentBindingException = ExceptionDispatchInfo.Capture(ex); } } message = argumentBindingException != null ? new InvocationBindingFailureMessage(invocationId, target, argumentBindingException) : BindInvocationMessage(invocationId, target, arguments, hasArguments, binder); } break; case HubProtocolConstants.StreamInvocationMessageType: { if (argumentsToken != null) { // We weren't able to bind the arguments because they came before the 'target', so try to bind now that we've read everything. try { var paramTypes = binder.GetParameterTypes(target); arguments = BindArguments(argumentsToken, paramTypes); } catch (Exception ex) { argumentBindingException = ExceptionDispatchInfo.Capture(ex); } } message = argumentBindingException != null ? new InvocationBindingFailureMessage(invocationId, target, argumentBindingException) : BindStreamInvocationMessage(invocationId, target, arguments, hasArguments, binder); } break; case HubProtocolConstants.StreamDataMessageType: if (itemToken != null) { var itemType = binder.GetStreamItemType(streamId); try { item = itemToken.ToObject(itemType, PayloadSerializer); } catch (JsonSerializationException ex) { return(new StreamBindingFailureMessage(streamId, ExceptionDispatchInfo.Capture(ex))); } } message = BindParamStreamMessage(streamId, item, hasItem, binder); break; case HubProtocolConstants.StreamItemMessageType: if (itemToken != null) { var returnType = binder.GetStreamItemType(invocationId); try { item = itemToken.ToObject(returnType, PayloadSerializer); } catch (JsonSerializationException ex) { return(new StreamBindingFailureMessage(invocationId, ExceptionDispatchInfo.Capture(ex))); }; } message = BindStreamItemMessage(invocationId, item, hasItem, binder); break; case HubProtocolConstants.CompletionMessageType: if (resultToken != null) { var returnType = binder.GetReturnType(invocationId); result = resultToken.ToObject(returnType, PayloadSerializer); } message = BindCompletionMessage(invocationId, error, result, hasResult, binder); break; case HubProtocolConstants.CancelInvocationMessageType: message = BindCancelInvocationMessage(invocationId); break; case HubProtocolConstants.PingMessageType: return(PingMessage.Instance); case HubProtocolConstants.CloseMessageType: return(BindCloseMessage(error)); case HubProtocolConstants.StreamCompleteMessageType: message = BindStreamCompleteMessage(streamId, error); break; case null: throw new InvalidDataException($"Missing required property '{TypePropertyName}'."); default: // Future protocol changes can add message types, old clients can ignore them return(null); } return(ApplyHeaders(message, headers)); } catch (JsonReaderException jrex) { throw new InvalidDataException("Error reading JSON.", jrex); } }
private async Task <object> InvokeCore(HttpServiceRequest request, Type resultReturnType, JsonSerializerSettings jsonSettings) { if (request == null) { throw new ArgumentNullException(nameof(request)); } request.TracingData = new TracingData { HostName = CurrentApplicationInfo.HostName?.ToUpperInvariant(), ServiceName = CurrentApplicationInfo.Name, RequestID = TracingContext.TryGetRequestID(), SpanID = Guid.NewGuid().ToString("N"), //Each call is new span ParentSpanID = TracingContext.TryGetSpanID(), SpanStartTime = DateTimeOffset.UtcNow, AbandonRequestBy = TracingContext.AbandonRequestBy }; PrepareRequest?.Invoke(request); while (true) { var config = GetConfig(); var clientCallEvent = EventPublisher.CreateEvent(); clientCallEvent.TargetService = ServiceName; clientCallEvent.RequestId = request.TracingData?.RequestID; clientCallEvent.TargetMethod = request.Target.MethodName; clientCallEvent.SpanId = request.TracingData?.SpanID; clientCallEvent.ParentSpanId = request.TracingData?.ParentSpanID; string responseContent; HttpResponseMessage response; var nodeAndLoadBalancer = await ServiceDiscovery.GetNode().ConfigureAwait(false); // can throw int?effectivePort = GetEffectivePort(nodeAndLoadBalancer.Node, config); if (effectivePort == null) { throw new ConfigurationException("Cannot access service. Service Port not configured. See tags to find missing configuration", unencrypted: new Tags { { "ServiceName", ServiceName }, { "Required configuration key", $"Discovery.{ServiceName}.DefaultPort" } }); } // The URL is only for a nice experience in Fiddler, it's never parsed/used for anything. var uri = BuildUri(nodeAndLoadBalancer.Node.Hostname, effectivePort.Value, config) + ServiceName; if (request.Target.MethodName != null) { uri += $".{request.Target.MethodName}"; } if (request.Target.Endpoint != null) { uri += $"/{request.Target.Endpoint}"; } try { Log.Debug(_ => _("ServiceProxy: Calling remote service. See tags for details.", unencryptedTags: new { remoteEndpoint = nodeAndLoadBalancer.Node.Hostname, remotePort = effectivePort, remoteServiceName = ServiceName, remoteMethodName = request.Target.MethodName })); clientCallEvent.TargetHostName = nodeAndLoadBalancer.Node.Hostname; clientCallEvent.TargetPort = effectivePort.Value; clientCallEvent.TargetEnvironment = nodeAndLoadBalancer.TargetEnvironment; request.Overrides = TracingContext.TryGetOverrides()?.ShallowCloneWithDifferentPreferredEnvironment(nodeAndLoadBalancer.PreferredEnvironment) ?? new RequestOverrides { PreferredEnvironment = nodeAndLoadBalancer.PreferredEnvironment }; string requestContent = _serializationTime.Time(() => JsonConvert.SerializeObject(request, jsonSettings)); var httpContent = new StringContent(requestContent, Encoding.UTF8, "application/json"); httpContent.Headers.Add(GigyaHttpHeaders.ProtocolVersion, HttpServiceRequest.ProtocolVersion); clientCallEvent.RequestStartTimestamp = Stopwatch.GetTimestamp(); try { response = await GetHttpClient(config).PostAsync(uri, httpContent).ConfigureAwait(false); responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false); } finally { clientCallEvent.ResponseEndTimestamp = Stopwatch.GetTimestamp(); } if (response.Headers.TryGetValues(GigyaHttpHeaders.ExecutionTime, out IEnumerable <string> values)) { var time = values.FirstOrDefault(); if (TimeSpan.TryParse(time, out TimeSpan executionTime)) { clientCallEvent.ServerTimeMs = executionTime.TotalMilliseconds; } } } catch (HttpRequestException ex) { Log.Error("The remote service failed to return a valid HTTP response. Continuing to next " + "host. See tags for URL and exception for details.", exception: ex, unencryptedTags: new { uri }); _hostFailureCounter.Increment("RequestFailure"); clientCallEvent.Exception = ex; EventPublisher.TryPublish(clientCallEvent); // fire and forget! if (nodeAndLoadBalancer.LoadBalancer != null) { nodeAndLoadBalancer.LoadBalancer.ReportUnreachable(nodeAndLoadBalancer.Node, ex); continue; } throw; } catch (TaskCanceledException ex) { _failureCounter.Increment("RequestTimeout"); Exception rex = new RemoteServiceException("The request to the remote service exceeded the " + "allotted timeout. See the 'RequestUri' property on this exception for the URL that was " + "called and the tag 'requestTimeout' for the configured timeout.", uri, ex, unencrypted: new Tags { { "requestTimeout", LastHttpClient?.Timeout.ToString() }, { "requestUri", uri } }); clientCallEvent.Exception = rex; EventPublisher.TryPublish(clientCallEvent); // fire and forget! throw rex; } if (response.Headers.Contains(GigyaHttpHeaders.ServerHostname) || response.Headers.Contains(GigyaHttpHeaders.ProtocolVersion)) { try { if (response.IsSuccessStatusCode) { var returnObj = _deserializationTime.Time(() => JsonConvert.DeserializeObject(responseContent, resultReturnType, jsonSettings)); clientCallEvent.ErrCode = 0; EventPublisher.TryPublish(clientCallEvent); // fire and forget! _successCounter.Increment(); return(returnObj); } else { Exception remoteException; try { remoteException = _deserializationTime.Time(() => ExceptionSerializer.Deserialize(responseContent)); } catch (Exception ex) { _applicationExceptionCounter.Increment("ExceptionDeserializationFailure"); throw new RemoteServiceException("The remote service returned a failure response " + "that failed to deserialize. See the 'RequestUri' property on this exception " + "for the URL that was called, the inner exception for the exact error and the " + "'responseContent' encrypted tag for the original response content.", uri, ex, unencrypted: new Tags { { "requestUri", uri } }, encrypted: new Tags { { "responseContent", responseContent } }); } _applicationExceptionCounter.Increment(); clientCallEvent.Exception = remoteException; EventPublisher.TryPublish(clientCallEvent); // fire and forget! if (remoteException is RequestException || remoteException is EnvironmentException) { ExceptionDispatchInfo.Capture(remoteException).Throw(); } if (remoteException is UnhandledException) { remoteException = remoteException.InnerException; } throw new RemoteServiceException("The remote service returned a failure response. See " + "the 'RequestUri' property on this exception for the URL that was called, and the " + "inner exception for details.", uri, remoteException, unencrypted: new Tags { { "requestUri", uri } }); } } catch (JsonException ex) { _failureCounter.Increment("Serialization"); Log.Error("The remote service returned a response with JSON that failed " + "deserialization. See the 'uri' tag for the URL that was called, the exception for the " + "exact error and the 'responseContent' encrypted tag for the original response content.", exception: ex, unencryptedTags: new { uri }, encryptedTags: new { responseContent }); clientCallEvent.Exception = ex; EventPublisher.TryPublish(clientCallEvent); // fire and forget! throw new RemoteServiceException("The remote service returned a response with JSON that " + "failed deserialization. See the 'RequestUri' property on this exception for the URL " + "that was called, the inner exception for the exact error and the 'responseContent' " + "encrypted tag for the original response content.", uri, ex, new Tags { { "responseContent", responseContent } }, new Tags { { "requestUri", uri } }); } } else { var exception = response.StatusCode == HttpStatusCode.ServiceUnavailable ? new Exception($"The remote service is unavailable (503) and is not recognized as a Gigya host at uri: {uri}") : new Exception($"The remote service returned a response but is not recognized as a Gigya host at uri: {uri}"); nodeAndLoadBalancer.LoadBalancer.ReportUnreachable(nodeAndLoadBalancer.Node, exception); _hostFailureCounter.Increment("NotGigyaHost"); if (response.StatusCode == HttpStatusCode.ServiceUnavailable) { Log.Error("The remote service is unavailable (503) and is not recognized as a Gigya host. Continuing to next host.", unencryptedTags: new { uri }); } else { Log.Error("The remote service returned a response but is not recognized as a Gigya host. Continuing to next host.", unencryptedTags: new { uri, statusCode = response.StatusCode }, encryptedTags: new { responseContent }); } clientCallEvent.ErrCode = 500001; //(int)GSErrors.General_Server_Error; EventPublisher.TryPublish(clientCallEvent); // fire and forget! } } }
void ThreadProc() { Data me; Mutex globalLock; MemoryMappedFile sharedData; long dataOffset; int SIZE = Marshal.SizeOf(typeof(Data)); int knownEntries = 0; try { Initialize(_identifier, out globalLock, out sharedData, out dataOffset, out me); } catch (Exception ex) { _pending = ExceptionDispatchInfo.Capture(ex); return; } finally { _workerStarted.Set(); } Dictionary <string, AnalysisProgress> response = null; Request request; bool abort = false; while (!abort) { while (!_requests.TryDequeue(out request)) { try { if (_identifier == null && _period.TotalDays < 1) { if (!_requestAdded.WaitOne(_period)) { request = Request.Send; break; } } else { _requestAdded.WaitOne(); } } catch (ObjectDisposedException) { request = Request.Abort; break; } } if (request == null) { continue; } else if (request == Request.Abort) { break; } try { if (!globalLock.WaitOne(LOCK_TIMEOUT)) { continue; } } catch (ObjectDisposedException) { break; } catch (AbandonedMutexException) { break; } try { if (request == Request.Send) { Debug.Assert(_identifier == null); response = ReadAllStatuses(sharedData, ref knownEntries); } else { Debug.Assert(_identifier != null); using (var accessor = sharedData.CreateViewAccessor(dataOffset, SIZE)) { me.ItemsInQueue = request.Update.Progress; me.MaximumItems = request.Update.Maximum; me.Seconds = request.Update.Seconds; me.Message = request.Update.Message; accessor.Write(0, ref me); } } } finally { try { globalLock.ReleaseMutex(); } catch (ObjectDisposedException) { abort = true; response = null; } } // Send the response outside the lock. if (response != null && _callback != null) { _callback(response); response = null; } } try { Uninitialize(_identifier, globalLock, sharedData, dataOffset); } catch (Exception ex) { _pending = ExceptionDispatchInfo.Capture(ex); } }
private static async Task <T> ExecuteWithRetriesHelper <T>( Func <int, Task <T> > function, int callCounter, int maxNumSuccessTries, int maxNumErrorTries, TimeSpan maxExecutionTime, DateTime startExecutionTime, Func <T, int, bool> retryValueFilter = null, Func <Exception, int, bool> retryExceptionFilter = null, IBackoffProvider onSuccessBackOff = null, IBackoffProvider onErrorBackOff = null) { T result = default(T); ExceptionDispatchInfo lastExceptionInfo = null; bool retry; do { retry = false; if (maxExecutionTime != Constants.INFINITE_TIMESPAN && maxExecutionTime != default(TimeSpan)) { DateTime now = DateTime.UtcNow; if (now - startExecutionTime > maxExecutionTime) { if (lastExceptionInfo == null) { throw new TimeoutException( $"ExecuteWithRetries has exceeded its max execution time of {maxExecutionTime}. Now is {LogFormatter.PrintDate(now)}, started at {LogFormatter.PrintDate(startExecutionTime)}, passed {now - startExecutionTime}"); } lastExceptionInfo.Throw(); } } int counter = callCounter; try { callCounter++; result = await function(counter); lastExceptionInfo = null; if (callCounter < maxNumSuccessTries || maxNumSuccessTries == INFINITE_RETRIES) // -1 for infinite retries { if (retryValueFilter != null) { retry = retryValueFilter(result, counter); } } if (retry) { TimeSpan?delay = onSuccessBackOff?.Next(counter); if (delay.HasValue) { await Task.Delay(delay.Value); } } } catch (Exception exc) { retry = false; if (callCounter < maxNumErrorTries || maxNumErrorTries == INFINITE_RETRIES) { if (retryExceptionFilter != null) { retry = retryExceptionFilter(exc, counter); } } if (!retry) { throw; } lastExceptionInfo = ExceptionDispatchInfo.Capture(exc); TimeSpan?delay = onErrorBackOff?.Next(counter); if (delay.HasValue) { await Task.Delay(delay.Value); } } } while (retry); return(result); }
/// <inheritdoc /> public override async Task <InputFormatterResult> ReadRequestBodyAsync( InputFormatterContext context, Encoding encoding) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (encoding == null) { throw new ArgumentNullException(nameof(encoding)); } var request = context.HttpContext.Request; var suppressInputFormatterBuffering = _options?.SuppressInputFormatterBuffering ?? _suppressInputFormatterBuffering; if (!request.Body.CanSeek && !suppressInputFormatterBuffering) { // JSON.Net does synchronous reads. In order to avoid blocking on the stream, we asynchronously // read everything into a buffer, and then seek back to the beginning. request.EnableBuffering(); Debug.Assert(request.Body.CanSeek); await request.Body.DrainAsync(CancellationToken.None); request.Body.Seek(0L, SeekOrigin.Begin); } using (var streamReader = context.ReaderFactory(request.Body, encoding)) { using (var jsonReader = new JsonTextReader(streamReader)) { jsonReader.ArrayPool = _charPool; jsonReader.CloseInput = false; var successful = true; Exception exception = null; void ErrorHandler(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs eventArgs) { successful = false; // Handle path combinations such as "" + "Property", "Parent" + "Property", or "Parent" + "[12]". var key = eventArgs.ErrorContext.Path; if (!string.IsNullOrEmpty(context.ModelName)) { if (string.IsNullOrEmpty(eventArgs.ErrorContext.Path)) { key = context.ModelName; } else if (eventArgs.ErrorContext.Path[0] == '[') { key = context.ModelName + eventArgs.ErrorContext.Path; } else { key = context.ModelName + "." + eventArgs.ErrorContext.Path; } } var metadata = GetPathMetadata(context.Metadata, eventArgs.ErrorContext.Path); var modelStateException = WrapExceptionForModelState(eventArgs.ErrorContext.Error); context.ModelState.TryAddModelError(key, modelStateException, metadata); _logger.JsonInputException(eventArgs.ErrorContext.Error); exception = eventArgs.ErrorContext.Error; // Error must always be marked as handled // Failure to do so can cause the exception to be rethrown at every recursive level and // overflow the stack for x64 CLR processes eventArgs.ErrorContext.Handled = true; } var type = context.ModelType; var jsonSerializer = CreateJsonSerializer(); jsonSerializer.Error += ErrorHandler; object model; try { model = jsonSerializer.Deserialize(jsonReader, type); } finally { // Clean up the error handler since CreateJsonSerializer() pools instances. jsonSerializer.Error -= ErrorHandler; ReleaseJsonSerializer(jsonSerializer); } if (successful) { if (model == null && !context.TreatEmptyInputAsDefaultValue) { // Some nonempty inputs might deserialize as null, for example whitespace, // or the JSON-encoded value "null". The upstream BodyModelBinder needs to // be notified that we don't regard this as a real input so it can register // a model binding error. return(InputFormatterResult.NoValue()); } else { return(InputFormatterResult.Success(model)); } } if (!(exception is JsonException || exception is OverflowException)) { var exceptionDispatchInfo = ExceptionDispatchInfo.Capture(exception); exceptionDispatchInfo.Throw(); } return(InputFormatterResult.Failure()); } } }
private async Task <RegistrationOperationStatus> ProvisionOverTcpUsingX509CertificateAsync( ProvisioningTransportRegisterMessage message, CancellationToken cancellationToken) { Debug.Assert(message.Security is SecurityProviderX509); cancellationToken.ThrowIfCancellationRequested(); X509Certificate2 clientCertificate = ((SecurityProviderX509)message.Security).GetAuthenticationCertificate(); var tlsSettings = new ClientTlsSettings( message.GlobalDeviceEndpoint, new List <X509Certificate> { clientCertificate }); var tcs = new TaskCompletionSource <RegistrationOperationStatus>(); Bootstrap bootstrap = new Bootstrap() .Group(s_eventLoopGroup) .Channel <TcpSocketChannel>() .Option(ChannelOption.TcpNodelay, true) .Option(ChannelOption.Allocator, UnpooledByteBufferAllocator.Default) .Handler(new ActionChannelInitializer <ISocketChannel>(ch => { ch.Pipeline.AddLast( new ReadTimeoutHandler(ReadTimeoutSeconds), new TlsHandler(tlsSettings), //TODO: Ensure SystemDefault is used. MqttEncoder.Instance, new MqttDecoder(isServer: false, maxMessageSize: MaxMessageSize), new ProvisioningChannelHandlerAdapter(message, tcs, cancellationToken)); })); if (Logging.IsEnabled) { Logging.Associate(bootstrap, this); } IPAddress[] addresses = await Dns.GetHostAddressesAsync(message.GlobalDeviceEndpoint).ConfigureAwait(false); if (Logging.IsEnabled) { Logging.Info(this, $"DNS resolved {addresses.Length} addresses."); } IChannel channel = null; Exception lastException = null; foreach (IPAddress address in addresses) { cancellationToken.ThrowIfCancellationRequested(); try { if (Logging.IsEnabled) { Logging.Info(this, $"Connecting to {address.ToString()}."); } channel = await bootstrap.ConnectAsync(address, Port).ConfigureAwait(false); break; } catch (AggregateException ae) { ae.Handle((ex) => { if (ex is ConnectException) // We will handle DotNetty.Transport.Channels.ConnectException { lastException = ex; if (Logging.IsEnabled) { Logging.Info( this, $"ConnectException trying to connect to {address.ToString()}: {ex.ToString()}"); } return(true); } return(false); // Let anything else stop the application. }); } } if (channel == null) { string errorMessage = "Cannot connect to Provisioning Service."; if (Logging.IsEnabled) { Logging.Error(this, errorMessage); } ExceptionDispatchInfo.Capture(lastException).Throw(); } return(await tcs.Task.ConfigureAwait(false)); }
/// <inheritdoc /> public override async Task <InputFormatterResult> ReadRequestBodyAsync( InputFormatterContext context, Encoding encoding) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (encoding == null) { throw new ArgumentNullException(nameof(encoding)); } var request = context.HttpContext.Request; var suppressInputFormatterBuffering = _options.SuppressInputFormatterBuffering; var readStream = request.Body; var disposeReadStream = false; if (!request.Body.CanSeek && !suppressInputFormatterBuffering) { // JSON.Net does synchronous reads. In order to avoid blocking on the stream, we asynchronously // read everything into a buffer, and then seek back to the beginning. var memoryThreshold = DefaultMemoryThreshold; var contentLength = request.ContentLength.GetValueOrDefault(); if (contentLength > 0 && contentLength < memoryThreshold) { // If the Content-Length is known and is smaller than the default buffer size, use it. memoryThreshold = (int)contentLength; } readStream = new FileBufferingReadStream(request.Body, memoryThreshold); await readStream.DrainAsync(CancellationToken.None); readStream.Seek(0L, SeekOrigin.Begin); disposeReadStream = true; } var successful = true; Exception exception = null; object model; using (var streamReader = context.ReaderFactory(readStream, encoding)) { using var jsonReader = new JsonTextReader(streamReader); jsonReader.ArrayPool = _charPool; jsonReader.CloseInput = false; var type = context.ModelType; var jsonSerializer = CreateJsonSerializer(context); jsonSerializer.Error += ErrorHandler; try { model = jsonSerializer.Deserialize(jsonReader, type); } finally { // Clean up the error handler since CreateJsonSerializer() pools instances. jsonSerializer.Error -= ErrorHandler; ReleaseJsonSerializer(jsonSerializer); if (disposeReadStream) { await readStream.DisposeAsync(); } } } if (successful) { if (model == null && !context.TreatEmptyInputAsDefaultValue) { // Some nonempty inputs might deserialize as null, for example whitespace, // or the JSON-encoded value "null". The upstream BodyModelBinder needs to // be notified that we don't regard this as a real input so it can register // a model binding error. return(InputFormatterResult.NoValue()); } else { return(InputFormatterResult.Success(model)); } } if (!(exception is JsonException || exception is OverflowException || exception is FormatException)) { // At this point we've already recorded all exceptions as an entry in the ModelStateDictionary. // We only need to rethrow an exception if we believe it needs to be handled by something further up // the stack. // JsonException, OverflowException, and FormatException are assumed to be only encountered when // parsing the JSON and are consequently "safe" to be exposed as part of ModelState. Everything else // needs to be rethrown. var exceptionDispatchInfo = ExceptionDispatchInfo.Capture(exception); exceptionDispatchInfo.Throw(); } return(InputFormatterResult.Failure()); void ErrorHandler(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs eventArgs) { successful = false; // When ErrorContext.Path does not include ErrorContext.Member, add Member to form full path. var path = eventArgs.ErrorContext.Path; var member = eventArgs.ErrorContext.Member?.ToString(); var addMember = !string.IsNullOrEmpty(member); if (addMember) { // Path.Member case (path.Length < member.Length) needs no further checks. if (path.Length == member.Length) { // Add Member in Path.Memb case but not for Path.Path. addMember = !string.Equals(path, member, StringComparison.Ordinal); } else if (path.Length > member.Length) { // Finally, check whether Path already ends with Member. if (member[0] == '[') { addMember = !path.EndsWith(member, StringComparison.Ordinal); } else { addMember = !path.EndsWith("." + member, StringComparison.Ordinal) && !path.EndsWith("['" + member + "']", StringComparison.Ordinal) && !path.EndsWith("[" + member + "]", StringComparison.Ordinal); } } } if (addMember) { path = ModelNames.CreatePropertyModelName(path, member); } // Handle path combinations such as ""+"Property", "Parent"+"Property", or "Parent"+"[12]". var key = ModelNames.CreatePropertyModelName(context.ModelName, path); exception = eventArgs.ErrorContext.Error; var metadata = GetPathMetadata(context.Metadata, path); var modelStateException = WrapExceptionForModelState(exception); context.ModelState.TryAddModelError(key, modelStateException, metadata); _logger.JsonInputException(exception); // Error must always be marked as handled // Failure to do so can cause the exception to be rethrown at every recursive level and // overflow the stack for x64 CLR processes eventArgs.ErrorContext.Handled = true; } }