friendship ended with social-app. php is my new best friend
1<?php 2 3namespace React\Promise\Internal; 4 5use React\Promise\PromiseInterface; 6use function React\Promise\_checkTypehint; 7use function React\Promise\resolve; 8use function React\Promise\set_rejection_handler; 9 10/** 11 * @internal 12 * 13 * @template-implements PromiseInterface<never> 14 */ 15final class RejectedPromise implements PromiseInterface 16{ 17 /** @var \Throwable */ 18 private $reason; 19 20 /** @var bool */ 21 private $handled = false; 22 23 /** 24 * @param \Throwable $reason 25 */ 26 public function __construct(\Throwable $reason) 27 { 28 $this->reason = $reason; 29 } 30 31 /** @throws void */ 32 public function __destruct() 33 { 34 if ($this->handled) { 35 return; 36 } 37 38 $handler = set_rejection_handler(null); 39 if ($handler === null) { 40 $message = 'Unhandled promise rejection with ' . $this->reason; 41 42 \error_log($message); 43 return; 44 } 45 46 try { 47 $handler($this->reason); 48 } catch (\Throwable $e) { 49 \preg_match('/^([^:\s]++)(.*+)$/sm', (string) $e, $match); 50 \assert(isset($match[1], $match[2])); 51 $message = 'Fatal error: Uncaught ' . $match[1] . ' from unhandled promise rejection handler' . $match[2]; 52 53 \error_log($message); 54 exit(255); 55 } 56 } 57 58 /** 59 * @template TRejected 60 * @param ?callable $onFulfilled 61 * @param ?(callable(\Throwable): (PromiseInterface<TRejected>|TRejected)) $onRejected 62 * @return PromiseInterface<($onRejected is null ? never : TRejected)> 63 */ 64 public function then(?callable $onFulfilled = null, ?callable $onRejected = null): PromiseInterface 65 { 66 if (null === $onRejected) { 67 return $this; 68 } 69 70 $this->handled = true; 71 72 try { 73 return resolve($onRejected($this->reason)); 74 } catch (\Throwable $exception) { 75 return new RejectedPromise($exception); 76 } 77 } 78 79 /** 80 * @template TThrowable of \Throwable 81 * @template TRejected 82 * @param callable(TThrowable): (PromiseInterface<TRejected>|TRejected) $onRejected 83 * @return PromiseInterface<TRejected> 84 */ 85 public function catch(callable $onRejected): PromiseInterface 86 { 87 if (!_checkTypehint($onRejected, $this->reason)) { 88 return $this; 89 } 90 91 /** 92 * @var callable(\Throwable):(PromiseInterface<TRejected>|TRejected) $onRejected 93 */ 94 return $this->then(null, $onRejected); 95 } 96 97 public function finally(callable $onFulfilledOrRejected): PromiseInterface 98 { 99 return $this->then(null, function (\Throwable $reason) use ($onFulfilledOrRejected): PromiseInterface { 100 return resolve($onFulfilledOrRejected())->then(function () use ($reason): PromiseInterface { 101 return new RejectedPromise($reason); 102 }); 103 }); 104 } 105 106 public function cancel(): void 107 { 108 $this->handled = true; 109 } 110 111 /** 112 * @deprecated 3.0.0 Use `catch()` instead 113 * @see self::catch() 114 */ 115 public function otherwise(callable $onRejected): PromiseInterface 116 { 117 return $this->catch($onRejected); 118 } 119 120 /** 121 * @deprecated 3.0.0 Use `always()` instead 122 * @see self::always() 123 */ 124 public function always(callable $onFulfilledOrRejected): PromiseInterface 125 { 126 return $this->finally($onFulfilledOrRejected); 127 } 128}