Exceptions

2018-10-08 09:17 更新

一般來說,Async遵循這種模式:

  • 調(diào)用一個async函數(shù)
  • 得到一個awaitable back
  • awaitthe awaitable得到結(jié)果

但是,有時Async函數(shù)可能會引發(fā)異常。好消息是,當您awaitthe awaitable的時候,Exception版本的代碼將拋出同一個Exception對象。

<?hh

namespace Hack\UserDocumentation\Async\Exceptions\Examples\BasicException;

async function exception_thrower(): Awaitable<void> {
  throw new \Exception("Return exception handle");
}

async function basic_exception(): Awaitable<void> {
  // the handle does not throw, but result will be an Exception objection.
  // Remember, this is the same as:
  //   $handle = exception_thrower();
  //   await $handle;
  await exception_thrower();
}

\HH\Asio\join(basic_exception());

Output


Fatal error: Uncaught exception 'Exception' with message 'Return exception handle' in /data/users/joelm/user-documentation/guides/hack/22-async/03-exceptions-examples/basic-exception.php:6
Stack trace:
#0 /data/users/joelm/user-documentation/guides/hack/22-async/03-exceptions-examples/basic-exception.php(14): Hack\UserDocumentation\Async\Exceptions\Examples\BasicException\exception_thrower()
#1 /data/users/joelm/user-documentation/guides/hack/22-async/03-exceptions-examples/basic-exception.php(17): Hack\UserDocumentation\Async\Exceptions\Examples\BasicException\basic_exception()
#2 {main}

使用基本的實用功能v()要么m()將忽略任何成功的等待結(jié)果,只是拋出一個等待結(jié)果的異常,如果其中一個結(jié)果是一個Exception。

<?hh

namespace Hack\UserDocumentation\Async\Exceptions\Examples\MultipleAwaitable;

async function exception_thrower(): Awaitable<void> {
  throw new \Exception("Return exception handle");
}

async function non_exception_thrower(): Awaitable<int> {
  return 2;
}

async function multiple_waithandle_exception(): Awaitable<void> {
  $handles = [exception_thrower(), non_exception_thrower()];
  // You will get a fatal error here with the exception thrown
  $results = await \HH\Asio\v($handles);
  // This won't happen
  var_dump($results);
}

\HH\Asio\join(multiple_waithandle_exception());

Output

Fatal error: Uncaught exception 'Exception' with message 'Return exception handle' in /data/users/joelm/user-documentation/guides/hack/22-async/03-exceptions-examples/multiple-awaitable-exception.php:6
Stack trace:
#0 /data/users/joelm/user-documentation/guides/hack/22-async/03-exceptions-examples/multiple-awaitable-exception.php(14): Hack\UserDocumentation\Async\Exceptions\Examples\MultipleAwaitable\exception_thrower()
#1 /data/users/joelm/user-documentation/guides/hack/22-async/03-exceptions-examples/multiple-awaitable-exception.php(21): Hack\UserDocumentation\Async\Exceptions\Examples\MultipleAwaitable\multiple_waithandle_exception()
#2 {main}

為了解決這個問題,并獲得成功的結(jié)果,我們可以使用所謂的效用函數(shù)HH\Asio\wrap()。它需要等待并返回預期結(jié)果或異常(如果被拋出)。它給出的例外是類型ResultOrExceptionWrapper

namespace HH\Asio {
  interface ResultOrExceptionWrapper<T> {
    public function isSucceeded(): bool;
    public function isFailed(): bool;
    public function getResult(): T;
    public function getException(): \Exception;
  }
}

以上面的例子和使用包裝機制,這就是代碼的樣子:

<?hh

namespace Hack\UserDocumentation\Async\Exceptions\Examples\Wrapping;

async function exception_thrower(): Awaitable<void> {
  throw new \Exception();
}

async function non_exception_thrower(): Awaitable<int> {
  return 2;
}

async function wrapping_exceptions(): Awaitable<void> {
  $handles = [\HH\Asio\wrap(exception_thrower()),
              \HH\Asio\wrap(non_exception_thrower())];
  // Since we wrapped, the results will contain both the exception and the
  // integer result
  $results = await \HH\Asio\v($handles);
  var_dump($results);
}

\HH\Asio\join(wrapping_exceptions());

Output

object(HH\Vector)#11 (2) {
  [0]=>
  object(HH\Asio\WrappedException)#4 (1) {
    ["exception":"HH\Asio\WrappedException":private]=>
    object(Exception)#2 (7) {
      ["message":protected]=>
      string(0) ""
      ["string":"Exception":private]=>
      string(0) ""
      ["code":protected]=>
      int(0)
      ["file":protected]=>
      string(104) "/data/users/joelm/user-documentation/guides/hack/22-async/03-exceptions-examples/wrapping-exceptions.php"
      ["line":protected]=>
      int(8)
      ["trace":"Exception":private]=>
      array(2) {
        [0]=>
        array(4) {
          ["file"]=>
          string(104) "/data/users/joelm/user-documentation/guides/hack/22-async/03-exceptions-examples/wrapping-exceptions.php"
          ["line"]=>
          int(16)
          ["function"]=>
          string(75) "Hack\UserDocumentation\Async\Exceptions\Examples\Wrapping\exception_thrower"
          ["args"]=>
          array(0) {
          }
        }
        [1]=>
        array(4) {
          ["file"]=>
          string(104) "/data/users/joelm/user-documentation/guides/hack/22-async/03-exceptions-examples/wrapping-exceptions.php"
          ["line"]=>
          int(24)
          ["function"]=>
          string(77) "Hack\UserDocumentation\Async\Exceptions\Examples\Wrapping\wrapping_exceptions"
          ["args"]=>
          array(0) {
          }
        }
      }
      ["previous":"Exception":private]=>
      NULL
    }
  }
  [1]=>
  object(HH\Asio\WrappedResult)#7 (1) {
    ["result":"HH\Asio\WrappedResult":private]=>
    int(2)
  }
}
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號