Не можете избежать вложенного будущего в Scala?

У меня есть вложенное будущее в моем приложении Scala. Я знаю, что всегда должен быть путь к методу выхода/возврата, и я считаю, что именно это предотвращает это вложенное будущее.

if (validRequest) {
  onComplete("a mongo query happens here") {
    case Success(result) =>
      if (result.isEmpty) {
        if (queryType.equals("id")) {
          onComplete("a different mongo query happens here") {
            case Success(result) =>
              complete(HttpResponse(200))
            case Failure(f) =>
              complete(HttpResponse(500))
          }
        }
      } else {
        complete(HttpResponse(200))
      }

    case Failure(f) =>
      complete(HttpResponse(500))
  }
} else {
  complete(HttpResponse(500))
}

Раньше, когда это не поддерживало запуск отдельного запроса монго, это выглядело следующим образом;

onComplete("a mongo query") {
  case Success(result) =>
    complete(HttpResponse(200))
  case Failure(f) =>
    complete(HttpResponse(500))
}

Итак, гораздо проще. Однако с необходимостью вложенного запроса все, похоже, пошло наперекосяк. Текущая ошибка, возвращаемая компилятором:

type mismatch;
[error]  found   : Unit
[error]  required: spray.routing.RequestContext => Unit
[error]                       if (queryType.equals("id")) {
[error]                       ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed

Обычно это подсказывает мне, что что-то не возвращается, то есть: оператор complete() не выполняется.

С указателем на ошибку единственное, что я мог себе представить, это то, что оператор switch может иметь результат, отличный от Success/Failure, что потенциально может привести к тому, что метод никогда не вернется. Я попытался добавить сегмент «case _ =>», который вернул стандартную ошибку 500, но безрезультатно.

Я также попытался использовать более упрощенный способ установки a var с ответом int (200 или 500) и отбрасыванием ответа complete() в конце, включая это... но, конечно, оператор complete() попадает рано, и потоки никогда не возвращают ожидаемые результаты.

Может ли кто-нибудь посоветовать мне, как лучше всего решить эту проблему?


person Eoghan    schedule 09.03.2017    source источник


Ответы (1)


Вы должны отладить его и посмотреть, где выдается это исключение. Из того, что я вижу на данный момент:

if (queryType.equals("id")) {
  onComplete("a different mongo query happens here") {
    case Success(result) =>
    complete(HttpResponse(200))
    case Failure(f) =>
    complete(HttpResponse(500))
  }
}

Это если нет другого, поэтому, когда это условие не выполняется, у вас есть Unit. Но я уверен, что вам нужно отладить его

Редактировать

Я заметил, что вы сказали, что компилятор указывает на ошибку. Попробуйте добавить еще к этому, если и посмотрите, поможет ли это

мне удалось его воспроизвести

  if (validRequest) {
    onComplete("a mongo query happens here") {
      case Success(result) =>
        if (result.isEmpty) {
          if (queryType.equals("id")) {
            onComplete("a different mongo query happens here") {
              case Success(result) =>
                complete(HttpResponse(200))
              case Failure(f) =>
                complete(HttpResponse(500))
            }
          }
          else {
            complete(HttpResponse(500))
          }
        } else {
          complete(HttpResponse(200))
        }

      case Failure(f) =>
        complete(HttpResponse(500))
    }
  } else {
    complete(HttpResponse(500))
  }

Код выше работает

person Kamil Banaszczyk    schedule 09.03.2017
comment
Еще один висящий оператор if/else. Большое спасибо за помощь! - person Eoghan; 09.03.2017