ReactiveMongo Найти одну ошибку документа

С помощью следующего бита кода я пытаюсь получить один документ на основе электронной почты пользователя, где электронная почта является частью сохраненного документа:

  def userByEmail(encryptedEmail: String): Future[Either[ServiceError, User]] = async {

    println(s"finding a user for email $encryptedEmail")

    val inlandDb = dbConn.db(dbName)
    val userColl = inlandDb[BSONCollection](userCollection)
    val found = await(
      userColl.find(BSONDocument(emailKey -> BSONString(encryptedEmail))).one[User]
    )
    println(s"found a user $found")

    found match {
      case Some(user) => Right(user)
      case None => Left(ServiceError("user not found"))
    }
  }

Пользователь для данного адреса электронной почты существует, поскольку я проверил его в консоли mongo. Что-то не так? Почему я не могу вернуть пользователя для моего поискового запроса.

Должен ли я иметь какой-либо индекс, определенный для электронной почты в моем пользовательском документе, чтобы он был доступен для поиска?

Я получаю следующую ошибку:

finding a user for email Ctkiaw/cbW8DxtRIxbtUYADq5bp6uW7tVryhpT57lKU=
failed java.lang.RuntimeException: None.get

None.get
java.lang.RuntimeException: None.get
    at scala.sys.package$.error(package.scala:27)
    at play.api.libs.iteratee.Iteratee$$anonfun$run$1.apply(Iteratee.scala:396)
    at play.api.libs.iteratee.Iteratee$$anonfun$run$1.apply(Iteratee.scala:389)
    at play.api.libs.iteratee.StepIteratee$$anonfun$fold$2.apply(Iteratee.scala:706)
    at play.api.libs.iteratee.StepIteratee$$anonfun$fold$2.apply(Iteratee.scala:706)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
    at play.api.libs.iteratee.Execution$trampoline$.executeScheduled(Execution.scala:109)
    at play.api.libs.iteratee.Execution$trampoline$.execute(Execution.scala:71)
    at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:40)
    at scala.concurrent.impl.Promise$DefaultPromise.tryComplete(Promise.scala:248)
    at scala.concurrent.Promise$class.complete(Promise.scala:55)
    at scala.concurrent.impl.Promise$DefaultPromise.complete(Promise.scala:153)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:23)
    at scala.concurrent.impl.ExecutionContextImpl$AdaptedForkJoinTask.exec(ExecutionContextImpl.scala:121)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.pollAndExecAll(ForkJoinPool.java:1253)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1346)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

Вот моя модель пользователя:

case class User(
  _id: Option[String],
  firstName: String,
  lastName: String,
  email: String,
  pass: String,
  address: Address,
  createDate: DateTime,
  activateDate: Option[DateTime],
  isUserActivated: Boolean,
  verificationDate: Option[DateTime]
)

Вот как я делаю преобразование:

  implicit object UserBSONHandler
    extends BSONDocumentReader[User] with BSONDocumentWriter[User] {

    def read(doc: BSONDocument): User = {
      User(
        _id = doc.getAs[String]("_id"),
        createDate = doc.getAs[BSONDateTime](createDateKey).map(dt => new DateTime(dt.value, DateTimeZone.UTC)).get,
        activateDate = doc.getAs[BSONDateTime](activateDateKey).map(dt => new DateTime(dt.value, DateTimeZone.UTC)),
        verificationDate = doc.getAs[BSONDateTime](verificationDateKey).map(dt => new DateTime(dt.value, DateTimeZone.UTC)),
        firstName = doc.getAs[String](firstNameKey).get,
        lastName = doc.getAs[String](lastNameKey).get,
        email = doc.getAs[String](emailKey).get,
        pass = doc.getAs[String](passKey).get,
        address = doc.getAs[Address](addressKey).get,
        isUserActivated = doc.getAs[Boolean](isUserActivatedKey).get
      )
    }
    def write(user: User): BSONDocument = {
      BSONDocument(
        firstNameKey -> user.firstName,
        lastNameKey -> user.lastName,
        emailKey -> user.email,
        passKey -> user.pass,
        addressKey -> user.address,
        createDateKey  -> user.createDate.toString(Iso8601DateFormatter),
        activateDateKey  -> user.activateDate.map(dt => dt.toString(Iso8601DateFormatter)),
        verificationDateKey  -> user.verificationDate.map(dt => dt.toString(Iso8601DateFormatter)),
        isUserActivatedKey  -> user.isUserActivated
      )
    }
  }

person joesan    schedule 24.10.2015    source источник
comment
Любые сообщения об ошибках? Или вы просто ничего не возвращаете?   -  person Barry    schedule 24.10.2015
comment
В этом блоке кода я не вижу, что emailKey определен, это строка?   -  person Barry    schedule 24.10.2015
comment
Это строка, а также поле в документе.   -  person joesan    schedule 24.10.2015
comment
Могу ли я увидеть определение пользователя? Как насчет BSONDocumentReader для пользователя? Вы пишете это вручную или через макросы?   -  person Barry    schedule 24.10.2015
comment
Я обновил пост со всей дополнительной информацией   -  person joesan    schedule 24.10.2015
comment
я думаю, что один из тех .gets вызывает проблему. Я думаю, что это находит запись, которую вы хотите, но терпит неудачу в чтении. Можете ли вы установить точку останова в читателе и изучить BSONDocument? в этой записи нет всех этих данных? Судя по исходным журналам, он не проходит дальше этого раздела с помощью Await.   -  person Barry    schedule 24.10.2015
comment
Да, ты прав! Проблема именно в том месте, где он считывает данные! Я попробую отладку! Но вы видите, что это все асинхронный код, и его нелегко отладить и увидеть!   -  person joesan    schedule 24.10.2015


Ответы (2)


Судя по журналам, похоже, что что-то не так в вашем чтении, исходный код, опубликованный выше, синтаксически в порядке, но сообщение об ошибке вместе с кодом регистрации помогло мне сосредоточиться на дальнейшей проверке вас BSONDocumentReader

person Barry    schedule 24.10.2015
comment
Вы попали в цель! Проблема была в преобразовании BSONDateTime! Я написал правильное решение! - person joesan; 24.10.2015

С помощью «Барри» я смог определить, где была проблема. Мне пришлось изменить метод чтения, как показано ниже:

def read(doc: BSONDocument): User = {
  User(
    _id = doc.getAs[String]("_id"),
    createDate = doc.getAs[String](createDateKey).map(dt => new DateTime(dt, DateTimeZone.UTC)).get,
    activateDate = doc.getAs[String](activateDateKey).map(dt => new DateTime(dt, DateTimeZone.UTC)),
    verificationDate = doc.getAs[String](verificationDateKey).map(dt => new DateTime(dt, DateTimeZone.UTC)),
    firstName = doc.getAs[String](firstNameKey).get,
    lastName = doc.getAs[String](lastNameKey).get,
    email = doc.getAs[String](emailKey).get,
    pass = doc.getAs[String](passKey).get,
    address = doc.getAs[Address](addressKey).get,
    isUserActivated = doc.getAs[Boolean](isUserActivatedKey).get
  )
}
person joesan    schedule 24.10.2015