static int ParseConflictingEntityPosition(StorageExtendedErrorInformation error) { var lines = error.ErrorMessage.Trim().Split('\n'); if (lines.Length != 3) { throw UnexpectedStorageResponseException.ConflictExceptionMessageShouldHaveExactlyThreeLines(error); } var semicolonIndex = lines[0].IndexOf(":", StringComparison.Ordinal); if (semicolonIndex == -1) { throw UnexpectedStorageResponseException.ConflictExceptionMessageShouldHaveSemicolonOnFirstLine(error); } int position; if (!int.TryParse(lines[0].Substring(0, semicolonIndex), out position)) { throw UnexpectedStorageResponseException.UnableToParseTextBeforeSemicolonToInteger(error); } return(position); }
internal void Handle(StorageException exception) { if (exception.RequestInformation.HttpStatusCode == (int)HttpStatusCode.PreconditionFailed) { throw ConcurrencyConflictException.StreamChangedOrExists(partition); } if (exception.RequestInformation.HttpStatusCode != (int)HttpStatusCode.Conflict) { ExceptionDispatchInfo.Capture(exception).Throw(); } var error = exception.RequestInformation.ExtendedErrorInformation; if (error.ErrorCode != "EntityAlreadyExists") { throw UnexpectedStorageResponseException.ErrorCodeShouldBeEntityAlreadyExists(error); } var position = ParseConflictingEntityPosition(error); Debug.Assert(position >= 0 && position < operations.Count); var conflicting = operations[position].Entity; if (conflicting == stream) { throw ConcurrencyConflictException.StreamChangedOrExists(partition); } var id = conflicting as EventIdEntity; if (id != null) { throw new DuplicateEventException(partition, id.Event.Id); } var @event = conflicting as EventEntity; if (@event != null) { throw ConcurrencyConflictException.EventVersionExists(partition, @event.Version); } var include = operations.Single(x => x.Entity == conflicting); throw IncludedOperationConflictException.Create(partition, include); }