2014-06-21 2 views
0

У меня есть способ создания zip-файла на Amazon S3, который использует абстракцию play-s3 Rinofly (не так уж и важно - главное - использование Future). Метод выглядит примерно так:Исключение глотания в цепочке метода сканирования Scala

def createZip(key: String): Future[String] = { 
    val bucket = //get S3 bucket 
    val zipFileName = //name of zip file 
    val futureFile = bucket get key //Returns Future[BucketFile] 
    futureFile 
     .map(bucketFile => newZipFile(bucketFile.name, bucketFile.content) //Create zip file from original key 
     .map(newZipFile => bucket + newZipFile) //Does an S3 PUT of the zip file in the bucket and returns Unit 
     .map(unit => zipFileName) //Maps the returned unit to the zip file name once the zip file has been created and properly uploaded to S3 
} 

Как вы можете видеть, метод принимает ключ S3 и возвращает имя соответствующего архива, который был создан.

Я обнаружил через REPL, что второй метод карты, который делает S3 для нового zip-файла, выдает исключение, поскольку учетные данные S3 не имеют разрешений. Нет проблем - я знаю, как это исправить.

Проблема в том, что я понятия не имел, что это было так, пока я не запустил все по строкам в REPL. Другими словами, метод дает ложный результат для успеха.

Когда я запускаю весь метод в РЕПЛ, я получаю это:

scala> val a = createZip("test.zip") 
a: scala.concurrent.Future[String] = [email protected] 
scala> import scala.concurrent.Await 
Await.result(a, 120.seconds) 
scala> res1: String = "test.zip" 

Результат должен был быть экземпляром Throwable (S3Exception FWIW).

Более того, когда я применяю onSuccess и onFailure обратные вызовы в REPL, это onSuccess, который срабатывает.

Очевидно, что я делаю что-то, чтобы проглотить или скрыть генерацию исключения в добавлении коллажа.

Я хотел бы знать, как убедиться, что все ошибки разоблачены.

+0

Ahh ... да, вы правы. Я просто «flatMap» и получил ожидаемый результат в REPL. Я удивлен тем, что компилятор или моя IDE не предупреждали о нарушении типа безопасности. Наверное, мне нужно продумать, что происходит более близко. В любом случае, пожалуйста, ответьте на свой ответ, чтобы я мог с вами связаться. – Vidya

ответ

1

bucket.addFuture[Unit] и не Unit. Так что на этой линии:

.map(unit => zipFileName) 

Вы на самом деле отображения Future[Unit] к String, который, как теряется ошибка, как вы бросаете, что ответ. Это map:

.map(newZipFile => bucket + newZipFile) 

должен стать flatMap правильно выравниваться от Future[Future[Unit]] к Future[Unit].

Компилятор недостаточно умен, чтобы сделать вывод, что вы не хотите отображать Future[Unit] => B, однако если бы вы добавили аннотацию типа, это не скомпилировалось.

.map{unit: Unit => zipFileName} // Would complain the type is not Future[Unit] 
Смежные вопросы