Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
206
src/Framework/ErrorBoundaries/BoundaryResult.php
Normal file
206
src/Framework/ErrorBoundaries/BoundaryResult.php
Normal file
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\ErrorBoundaries;
|
||||
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Result wrapper for error boundary operations
|
||||
*
|
||||
* @template T
|
||||
*/
|
||||
final readonly class BoundaryResult
|
||||
{
|
||||
private function __construct(
|
||||
private mixed $value,
|
||||
private ?Throwable $error,
|
||||
private bool $isSuccess,
|
||||
private ?string $boundaryName = null
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create successful result
|
||||
*
|
||||
* @template U
|
||||
* @param U $value
|
||||
* @return BoundaryResult<U>
|
||||
*/
|
||||
public static function success(mixed $value): self
|
||||
{
|
||||
return new self($value, null, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create failed result
|
||||
*
|
||||
* @template U
|
||||
* @param Throwable $error
|
||||
* @param string|null $boundaryName
|
||||
* @return BoundaryResult<U>
|
||||
*/
|
||||
public static function failure(Throwable $error, ?string $boundaryName = null): self
|
||||
{
|
||||
return new self(null, $error, false, $boundaryName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if operation was successful
|
||||
*/
|
||||
public function isSuccess(): bool
|
||||
{
|
||||
return $this->isSuccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if operation failed
|
||||
*/
|
||||
public function isFailure(): bool
|
||||
{
|
||||
return ! $this->isSuccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the result value (only if successful)
|
||||
*
|
||||
* @return T
|
||||
* @throws BoundaryFailedException
|
||||
*/
|
||||
public function getValue(): mixed
|
||||
{
|
||||
if (! $this->isSuccess) {
|
||||
throw new BoundaryFailedException(
|
||||
'Cannot get value from failed result',
|
||||
$this->boundaryName ?? 'unknown',
|
||||
$this->error
|
||||
);
|
||||
}
|
||||
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the error (only if failed)
|
||||
*/
|
||||
public function getError(): ?Throwable
|
||||
{
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get boundary name
|
||||
*/
|
||||
public function getBoundaryName(): ?string
|
||||
{
|
||||
return $this->boundaryName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value or return default if failed
|
||||
*
|
||||
* @param T $default
|
||||
* @return T
|
||||
*/
|
||||
public function getValueOrDefault(mixed $default): mixed
|
||||
{
|
||||
return $this->isSuccess ? $this->value : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value or execute fallback function if failed
|
||||
*
|
||||
* @param callable(): T $fallback
|
||||
* @return T
|
||||
*/
|
||||
public function getValueOrElse(callable $fallback): mixed
|
||||
{
|
||||
return $this->isSuccess ? $this->value : $fallback();
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform the result if successful
|
||||
*
|
||||
* @template U
|
||||
* @param callable(T): U $mapper
|
||||
* @return BoundaryResult<U>
|
||||
*/
|
||||
public function map(callable $mapper): self
|
||||
{
|
||||
if (! $this->isSuccess) {
|
||||
return new self(null, $this->error, false, $this->boundaryName);
|
||||
}
|
||||
|
||||
try {
|
||||
$transformed = $mapper($this->value);
|
||||
|
||||
return new self($transformed, null, true, $this->boundaryName);
|
||||
} catch (Throwable $e) {
|
||||
return new self(null, $e, false, $this->boundaryName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Chain another operation if current result is successful
|
||||
*
|
||||
* @template U
|
||||
* @param callable(T): BoundaryResult<U> $mapper
|
||||
* @return BoundaryResult<U>
|
||||
*/
|
||||
public function flatMap(callable $mapper): self
|
||||
{
|
||||
if (! $this->isSuccess) {
|
||||
return new self(null, $this->error, false, $this->boundaryName);
|
||||
}
|
||||
|
||||
try {
|
||||
return $mapper($this->value);
|
||||
} catch (Throwable $e) {
|
||||
return new self(null, $e, false, $this->boundaryName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute callback if result is successful
|
||||
*
|
||||
* @param callable(T): void $callback
|
||||
* @return self
|
||||
*/
|
||||
public function onSuccess(callable $callback): self
|
||||
{
|
||||
if ($this->isSuccess) {
|
||||
$callback($this->value);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute callback if result failed
|
||||
*
|
||||
* @param callable(Throwable): void $callback
|
||||
* @return self
|
||||
*/
|
||||
public function onFailure(callable $callback): self
|
||||
{
|
||||
if (! $this->isSuccess && $this->error) {
|
||||
$callback($this->error);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to array representation
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'success' => $this->isSuccess,
|
||||
'value' => $this->isSuccess ? $this->value : null,
|
||||
'error' => $this->error?->getMessage(),
|
||||
'boundary' => $this->boundaryName,
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user