### Install Laravel Boost Source: https://github.com/maxiviper117/result-flow/blob/main/README.md Installs the Laravel Boost assets to enable AI-assisted code generation for ResultFlow within a Laravel application. ```bash php artisan boost:install ``` -------------------------------- ### Complete Pipeline Example with Validation and Persistence (PHP) Source: https://context7.com/maxiviper117/result-flow/llms.txt Demonstrates a full validation and persistence workflow using the Result Flow library. It includes input validation, data transformation, database interaction with error handling, and logging of outcomes. ```php use Maxiviper117\ResultFlow\Result; $input = ['email' => 'user@example.com', 'name' => 'John']; $result = Result::ok($input, ['request_id' => (string) Str::uuid()]) // Validation guards ->ensure(fn ($data) => isset($data['email']), 'Email is required') ->ensure( fn ($data) => filter_var($data['email'], FILTER_VALIDATE_EMAIL), fn ($data) => "Invalid email: {$data['email']}" ) ->ensure(fn ($data) => strlen($data['name'] ?? '') >= 2, 'Name must be at least 2 characters') // Transform ->map(fn ($data) => [ ...$data, 'email' => strtolower($data['email']), 'created_at' => date('Y-m-d H:i:s') ]) // Persist (may return Result or throw) ->then(fn ($user, $meta) => Result::defer(fn () => $userRepository->create($user))) // Handle specific exceptions ->catchException([ UniqueConstraintException::class => fn ($e) => Result::fail([ 'code' => 'DUPLICATE_EMAIL', 'message' => 'Email already exists' ]) ]) // Log outcomes ->onSuccess(fn ($user) => logger()->info('User created', ['id' => $user['id']])) ->onFailure(fn ($error, $meta) => logger()->warning('User creation failed', 'error' => $error, 'request_id' => $meta['request_id'] ])); // Final output return $result->match( onSuccess: fn ($user, $meta) => response()->json(['ok' => true, 'data' => $user], 201), onFailure: fn ($error, $meta) => response()->json(['ok' => false, 'error' => $error], 400) ); ``` -------------------------------- ### Install Result Flow via Composer Source: https://github.com/maxiviper117/result-flow/blob/main/README.md Use this command to add the Result Flow package to your PHP project dependencies. ```bash composer require maxiviper117/result-flow ``` -------------------------------- ### Example Conventional Commit Messages for Release Please Source: https://github.com/maxiviper117/result-flow/blob/main/RELEASE.md Demonstrates various conventional commit message formats used to trigger different types of version bumps (feat, fix, perf, breaking changes) or no release for the Release Please automation. ```markdown feat: add new user authentication module This commit introduces a new module for handling user authentication, including registration and login functionalities. BREAKING CHANGE: The previous authentication method is deprecated and will be removed in a future release. ``` ```markdown fix: resolve issue with data fetching on profile page Corrects a bug where user profile data was not loading correctly under certain conditions. ``` ```markdown perf: optimize database query for user list Improves the performance of the query used to retrieve the list of users. ``` ```markdown chore: update dependencies to latest versions This commit updates various project dependencies to their latest stable versions. ``` ```markdown docs: improve README with setup instructions Adds more detailed instructions on how to set up the project locally. ``` ```markdown feat!: remove deprecated API endpoint This commit removes the old `/api/v1/users` endpoint. Clients should migrate to the new `/api/v2/users` endpoint. ``` -------------------------------- ### Create Success and Failure Results Source: https://context7.com/maxiviper117/result-flow/llms.txt Demonstrates how to instantiate Ok and Fail results, including metadata and value retrieval methods. ```php use Maxiviper117\ResultFlow\Result; // Basic success result $result = Result::ok(['id' => 1, 'name' => 'John'], ['request_id' => 'r-123']); // Basic failure result $result = Result::fail('Invalid email format', ['field' => 'email', 'step' => 'validation']); // Failure with preserved failed value $result = Result::failWithValue('Invalid email', ['email' => 'bad-email'], ['step' => 'validation']); ``` -------------------------------- ### Constructing Result Flow in PHP Source: https://github.com/maxiviper117/result-flow/blob/main/resources/boost/skills/result-flow/references/constructing.md Demonstrates the initialization of a result flow using the defer method to handle input callbacks and chaining subsequent validation logic. ```php $result = Result::defer(fn () => $input) ->then(fn (array $payload) => validate($payload)); ``` -------------------------------- ### Chaining Result Flow Operations Source: https://github.com/maxiviper117/result-flow/blob/main/resources/boost/skills/result-flow/references/chaining.md Demonstrates how to chain operations using the Result Flow pattern. It uses ensure to validate data and then to persist the result, ensuring a clean success-path flow. ```php $result = Result::ok($dto) ->ensure(fn ($v) => isValid($v), 'Invalid input') ->then(fn ($v) => persist($v)); ``` -------------------------------- ### Wrap Callables and Normalize Outputs Source: https://context7.com/maxiviper117/result-flow/llms.txt Shows how to wrap throwing callables with Result::of and normalize mixed return types using Result::defer. ```php use Maxiviper117\ResultFlow\Result; // Wrap throwing callable $result = Result::of(fn () => json_decode('invalid json', true, 512, JSON_THROW_ON_ERROR)); // Normalize output $result = Result::defer(fn () => 42); $result = Result::defer(fn () => Result::fail('Already failed')); ``` -------------------------------- ### Perform Chained Result Operations Source: https://github.com/maxiviper117/result-flow/blob/main/README.md Demonstrates creating a Result, validating data with ensure, and transforming it with then. The match method is used to handle the final output for both success and failure cases. ```php use Maxiviper117\ResultFlow\Result; $result = Result::ok(['order_id' => 123, 'total' => 42], ['request_id' => 'r-1']) ->ensure(fn (array $order) => $order['total'] > 0, 'Order total must be positive') ->then(fn (array $order) => Result::ok([ 'saved' => true, 'id' => $order['order_id'], ])); $output = $result->match( onSuccess: fn (array $v) => ['ok' => true, 'data' => $v], onFailure: fn ($e) => ['ok' => false, 'error' => (string) $e], ); ``` -------------------------------- ### Perform Resource-Safe Operations Source: https://github.com/maxiviper117/result-flow/blob/main/README.md Uses the bracket pattern to safely acquire, use, and release resources like file handles. ```php use Maxiviper117\ResultFlow\Result; $result = Result::bracket( acquire: fn () => fopen($path, 'r'), use: fn ($handle) => fread($handle, 100), release: fn ($handle) => fclose($handle), ); ``` -------------------------------- ### Execute Deferred Retry with Result-Flow Source: https://github.com/maxiviper117/result-flow/blob/main/resources/boost/skills/result-flow/references/retries.md Demonstrates the use of retryDefer to handle operations that may return a Result or throw an exception. It includes configuration for maximum attempts, delay intervals, and exponential backoff, followed by a terminal failure handler. ```php $result = Result::retryDefer(3, fn () => send($payload), delay: 100, exponential: true) ->otherwise(fn ($error) => mapTerminalFailure($error)); ``` -------------------------------- ### Safe Resource Operations with Bracket in PHP Source: https://context7.com/maxiviper117/result-flow/llms.txt Safely acquires a resource, uses it, and ensures cleanup happens even on failure using the `Result::bracket` method. This is demonstrated with file handling and database connections, ensuring the release function is always called. ```php use Maxiviper117\ResultFlow\Result; $result = Result::bracket( acquire: fn () => fopen('/path/to/file.txt', 'r'), use: fn ($handle) => fread($handle, 1024), release: fn ($handle) => fclose($handle) // Always called after use ); // Database connection example $result = Result::bracket( acquire: fn () => new PDO($dsn, $user, $pass), use: fn (PDO $db) => $db->query('SELECT * FROM users')->fetchAll(), release: fn (PDO $db) => $db = null // Connection released ); // If use() fails, release() is still called // If release() throws after use() failure, original error is preserved with release exception in meta ``` -------------------------------- ### Branch-aware output handling with match Source: https://github.com/maxiviper117/result-flow/blob/main/resources/boost/skills/result-flow/references/boundaries.md Demonstrates the use of the match method to handle both success and failure branches of a Result object. This is the primary way to finalize a result into an application-facing response. ```php return $result->match( onSuccess: fn ($value) => [...], onFailure: fn ($error) => [...], ); ``` -------------------------------- ### Conditional Failure Mapping and Recovery with `otherwise` Source: https://github.com/maxiviper117/result-flow/blob/main/resources/boost/skills/result-flow/references/failure-handling.md Demonstrates how to use the `otherwise` method for conditional failure mapping and recovery. It allows defining a callback function to handle errors and associated metadata, enabling custom error normalization. This is useful when specific conditions dictate how a failure should be processed or transformed. ```php $result = callService() ->catchException([...]) ->otherwise(fn ($e, $meta) => normalizeError($e, $meta)); ``` -------------------------------- ### Retry Execution Methods Source: https://github.com/maxiviper117/result-flow/blob/main/resources/boost/skills/result-flow/references/retries.md Methods for implementing retry logic including simple retries, deferred execution, and advanced retrier configurations. ```APIDOC ## Retry Execution Methods ### Description Provides mechanisms to handle transient failures through various retry strategies. ### Methods - **retry**: Simple retry policy for basic operations. - **retryDefer**: Handles callbacks that return a Result or throw exceptions. - **retrier**: Advanced configuration for predicates, hooks, and backoff strategies. ### Parameters - **attempts** (int) - Required - Maximum number of retry attempts. - **callback** (callable) - Required - The operation to execute. - **delay** (int) - Optional - Delay between attempts in milliseconds. - **exponential** (bool) - Optional - Whether to use exponential backoff. ### Request Example ```php $result = Result::retryDefer(3, fn () => send($payload), delay: 100, exponential: true) ->otherwise(fn ($error) => mapTerminalFailure($error)); ``` ### Response #### Success Response (200) - **Result** (object) - The successful result of the operation. #### Error Handling - Use `otherwise()` to map terminal failures after all retry attempts are exhausted. ``` -------------------------------- ### Manual Trigger for Release Please Workflow Source: https://github.com/maxiviper117/result-flow/blob/main/RELEASE.md Provides a bash command to manually trigger a release with a specific version using an empty commit and conventional message, useful when automated triggers fail. ```bash git commit --allow-empty -m "chore: release 1.0.1" -m "Release-As: 1.0.1" git push ``` -------------------------------- ### Manipulate Metadata and Inspect Errors in Result-Flow Source: https://github.com/maxiviper117/result-flow/blob/main/resources/boost/skills/result-flow/references/debugging-metadata.md Demonstrates how to merge metadata into a result pipeline and use inspectError for side-effect-based logging. This pattern ensures that diagnostic information is captured without mutating the core pipeline flow. ```php $result = $result ->mergeMeta(['operation' => 'checkout']) ->inspectError(fn ($e, $meta) => logger()->warning('failed', compact('e', 'meta'))); ``` -------------------------------- ### Result-Flow API Overview Source: https://github.com/maxiviper117/result-flow/blob/main/resources/boost/skills/result-flow/references/public-api-whitelist.md A comprehensive reference of the public API methods for the Result-Flow library, categorized by their operational purpose. ```APIDOC ## Result-Flow Public API ### Static Constructors - `ok`, `fail`, `failWithValue`, `of`, `defer`, `retry`, `retryDefer`, `retrier`, `bracket` - `combine`, `combineAll` - `mapItems`, `mapAll`, `mapCollectErrors` ### Branch and Metadata Operations - `isOk`, `isFail`, `value`, `error`, `meta` - `tapMeta`, `mapMeta`, `mergeMeta` - `tap`, `onSuccess`, `inspect`, `onFailure`, `inspectError` ### Transform and Chaining - `map`, `mapError`, `ensure`, `then`, `flatMap`, `thenUnsafe` - `otherwise`, `catchException`, `recover` ### Completion and Unwrapping - `match`, `matchException` - `unwrap`, `unwrapOr`, `unwrapOrElse`, `getOrThrow`, `throwIfFail` - `toArray`, `toDebugArray`, `toJson`, `toXml`, `toResponse` ### Constraints - Do not invent APIs. - Do not use internal helper classes directly. - Keep boundary completion explicit. ``` -------------------------------- ### Handle Specific Exceptions with catchException Source: https://context7.com/maxiviper117/result-flow/llms.txt Matches Throwable errors based on their class type to provide specialized recovery strategies. Includes a fallback mechanism for unhandled exceptions. ```php use Maxiviper117\ResultFlow\Result; use RuntimeException; use InvalidArgumentException; $result = Result::of(fn () => riskyOperation()) ->catchException([ RuntimeException::class => fn (RuntimeException $e, array $meta) => Result::fail([ 'code' => 'RUNTIME_ERROR', 'message' => $e->getMessage() ], $meta), InvalidArgumentException::class => fn (InvalidArgumentException $e) => Result::ok([ 'recovered' => true, 'default_value' => 'fallback' ]) ], fallback: fn ($error, $meta) => Result::fail('Unhandled error: ' . $error)); ``` -------------------------------- ### Exhaustive Branch Handling with match Source: https://context7.com/maxiviper117/result-flow/llms.txt Forces explicit handling of both success and failure branches, ensuring all outcomes are addressed. Also provides exception-aware matching for complex error scenarios. ```php use Maxiviper117\ResultFlow\Result; $result = Result::ok(['id' => 123, 'status' => 'active'], ['request_id' => 'r-1']); $response = $result->match( onSuccess: fn (array $user, array $meta) => [ 'ok' => true, 'data' => $user, 'request_id' => $meta['request_id'] ], onFailure: fn ($error, array $meta) => [ 'ok' => false, 'error' => (string) $error, 'request_id' => $meta['request_id'] ] ); // Exception-aware matching $response = $result->matchException( exceptionHandlers: [ RuntimeException::class => fn ($e, $meta) => ['error' => 'runtime', 'message' => $e->getMessage()], InvalidArgumentException::class => fn ($e) => ['error' => 'validation', 'message' => $e->getMessage()] ], onSuccess: fn ($value) => ['ok' => true, 'data' => $value], onUnhandled: fn ($error) => ['ok' => false, 'error' => (string) $error] ); ``` -------------------------------- ### Chaining Operations on Result Objects Source: https://github.com/maxiviper117/result-flow/blob/main/resources/boost/skills/result-flow/references/chaining.md This section details various methods for chaining operations on Result objects, including mapping, ensuring conditions, and handling exceptions. ```APIDOC ## Chaining Operations on Result Objects ### Description This section details various methods for chaining operations on Result objects, including mapping, ensuring conditions, and handling exceptions. ### Decision Table for Chaining | Need | Method | |--------------------------------------------------|-------------| | Pure success transform | `map` | | Guard success with predicate | `ensure` | | Chain step returning value/`Result` with exception capture | `then` / `flatMap` | | Intentionally bubble exceptions | `thenUnsafe` | | Normalize failure payload | `mapError` | ### Guidance - Run `ensure` early for cheaper failure. - Use `then` for branch-aware step composition. - Use `thenUnsafe` only with explicit exception boundary intent. ### Anti-patterns - Returning `Result` from `map` callbacks. - Using `thenUnsafe` by default. ### Example Usage ```php $result = Result::ok($dto) ->ensure(fn ($v) => isValid($v), 'Invalid input') ->then(fn ($v) => persist($v)); ``` ### Methods Overview #### `map` - **Description**: Applies a transformation function to the success value of a Result. - **Use Case**: Pure success transform. #### `ensure` - **Description**: Guards the success path with a predicate function. If the predicate returns false, the Result becomes a failure. - **Use Case**: Guard success with a predicate. #### `then` - **Description**: Chains a step that returns a value or a `Result`. Captures exceptions thrown by the chained step. - **Use Case**: Chain step returning value/`Result` with exception capture. #### `flatMap` - **Description**: Similar to `then`, but specifically designed for chaining operations that return a `Result`. - **Use Case**: Chain step returning value/`Result` with exception capture. #### `thenUnsafe` - **Description**: Chains a step and intentionally bubbles up any exceptions thrown. - **Use Case**: Intentionally bubble exceptions. #### `mapError` - **Description**: Applies a transformation function to the failure value of a Result. - **Use Case**: Normalize failure payload. ``` -------------------------------- ### Convert Failure to Success with recover Source: https://context7.com/maxiviper117/result-flow/llms.txt Unconditionally transforms any failure state into a success state using a provided callback. Useful for defining default fallback values. ```php use Maxiviper117\ResultFlow\Result; $result = Result::fail('API timeout', ['service' => 'payment']) ->recover(fn ($error, $meta) => [ 'fallback' => true, 'reason' => $error, 'service' => $meta['service'] ?? 'unknown' ]); ``` -------------------------------- ### Chain and Transform Results Source: https://context7.com/maxiviper117/result-flow/llms.txt Utilize then/flatMap for chaining operations and map for transforming success values without changing the result branch. ```php use Maxiviper117\ResultFlow\Result; // Chaining operations $result = Result::ok(['order_id' => 123, 'total' => 100]) ->then(fn (array $order) => Result::ok(['total' => $order['total'] * 0.1])); // Transforming values $result = Result::ok(['id' => 1, 'total' => 100]) ->map(fn (array $order) => $order['id']); ``` -------------------------------- ### Metadata Management in Result Flow (PHP) Source: https://context7.com/maxiviper117/result-flow/llms.txt Manages contextual metadata that flows through the entire Result chain for observability and debugging. Includes methods to merge, map, and tap metadata, allowing for logging and transformation. ```php use Maxiviper117\ResultFlow\Result; $result = Result::ok(['id' => 1], ['request_id' => 'r-123']) // Merge additional metadata ->mergeMeta(['operation' => 'user.create', 'timestamp' => time()]) // Transform metadata completely ->mapMeta(fn ($meta) => [...$meta, 'processed' => true]) // Side-effect on metadata (logging, etc.) ->tapMeta(fn ($meta) => logger()->info('Processing', $meta)) // Continue chain ->then(fn ($value) => Result::ok($value, ['step' => 'validated'])); $result->meta(); // All accumulated metadata ``` -------------------------------- ### Aggregate Results with combine and combineAll - PHP Source: https://context7.com/maxiviper117/result-flow/llms.txt Methods for combining multiple Result instances into a single Result. `combine` uses a fail-fast strategy and merges metadata, stopping at the first failure. `combineAll` processes all Results and collects all errors if any failures occur. ```php use Maxiviper117\ResultFlow\Result; $userResult = Result::ok(['id' => 1], ['step' => 'user']); $profileResult = Result::ok(['bio' => 'Dev'], ['step' => 'profile']); $settingsResult = Result::fail('Settings not found'); // combine: fail-fast on first failure, merges metadata $result = Result::combine([$userResult, $profileResult]); // Result: ok([['id' => 1], ['bio' => 'Dev']], ['step' => 'user', 'step' => 'profile']) // With failure - stops at first fail $result = Result::combine([$userResult, $settingsResult, $profileResult]); // Result: fail('Settings not found') - profileResult never checked // combineAll: collects ALL errors, processes everything $result = Result::combineAll([ Result::fail('Email invalid'), Result::ok(['valid' => true]), Result::fail('Password too short') ]); // Result: fail(['Email invalid', 'Password too short']) ``` -------------------------------- ### Execute Deferred Operations Source: https://github.com/maxiviper117/result-flow/blob/main/README.md Wraps a function call in a deferred Result to allow for lazy execution and chaining. ```php use Maxiviper117\ResultFlow\Result; $result = Result::defer(fn () => loadUserById($id)) ->then(fn (array $user) => Result::ok(normalizeUser($user))); ``` -------------------------------- ### Decision Table for Batch Processing Source: https://github.com/maxiviper117/result-flow/blob/main/resources/boost/skills/result-flow/references/batch-processing.md This section details various methods for processing batches of items, categorized by input type and the desired processing outcome (e.g., per-item results, fail-fast aggregation, collecting errors). ```APIDOC ## Batch Processing Decision Table This table outlines different strategies for processing batches of items, depending on the input and the desired output. ### Input: Raw items | Need | Method | |--------------------------|--------------------| | Per-item `Result` map | `mapItems` | | Fail-fast aggregate | `mapAll` | | Collect-all keyed errors | `mapCollectErrors` | ### Input: Existing `Result[]` | Need | Method | |--------------------------|-------------| | Fail-fast aggregate | `combine` | | Collect-all failures | `combineAll`| ### Guidance - Preserve keys for UI/form diagnostics. - Choose collect-all when consumer needs complete error visibility. ### Anti-patterns - Fail-fast in validation scenarios requiring full error reporting. - Mixing raw items and `Result[]` paths in one function. ### Example Usage ```php $result = Result::mapCollectErrors($rows, fn ($row, $key) => validateRow($row, $key)); ``` ``` -------------------------------- ### Extract Values with unwrap Methods - PHP Source: https://context7.com/maxiviper117/result-flow/llms.txt Provides methods to extract the underlying value from a Result object, with strategies for handling failures. `unwrap` throws on failure, `unwrapOr` provides an eager default, `unwrapOrElse` provides a lazy default with error access, `getOrThrow` allows custom exceptions, and `throwIfFail` is chainable for immediate exception throwing. ```php use Maxiviper117\ResultFlow\Result; $success = Result::ok(['id' => 1]); $failure = Result::fail('Not found', ['entity' => 'user']); // unwrap: throws on failure $value = $success->unwrap(); // ['id' => 1] // $failure->unwrap(); // Throws RuntimeException // unwrapOr: eager default $value = $failure->unwrapOr(['id' => 0]); // ['id' => 0] // unwrapOrElse: lazy default with access to error and meta $value = $failure->unwrapOrElse(fn ($error, $meta) => [ 'id' => null, 'error' => $error, 'entity' => $meta['entity'] ]); // getOrThrow: custom exception $value = $failure->getOrThrow(fn ($error, $meta) => new NotFoundException("Entity {$meta['entity']} not found: {$error}") ); // throwIfFail: chainable, throws on failure, returns self on success $result = Result::ok($data) ->then(new ValidateAction()) ->throwIfFail() // Throws if validation failed ->then(new PersistAction()); ``` -------------------------------- ### Map Collect Errors in PHP Source: https://github.com/maxiviper117/result-flow/blob/main/resources/boost/skills/result-flow/references/batch-processing.md Demonstrates how to process a collection of rows using the mapCollectErrors method. This approach is useful when you need to validate multiple items and collect all errors instead of failing immediately. ```php $result = Result::mapCollectErrors($rows, fn ($row, $key) => validateRow($row, $key)); ``` -------------------------------- ### Batch Process Collections with map Methods - PHP Source: https://context7.com/maxiviper117/result-flow/llms.txt Functions for processing collections where each item might produce a Result. `mapItems` returns an array of Results, one for each item. `mapAll` aggregates results with a fail-fast strategy. `mapCollectErrors` processes all items and collects all errors encountered. ```php use Maxiviper117\ResultFlow\Result; $rows = [ 'user1' => ['email' => 'valid@example.com'], 'user2' => ['email' => 'invalid-email'], 'user3' => ['email' => 'also@valid.com'] ]; $validator = fn (array $row, string $key): Result => filter_var($row['email'] ?? null, FILTER_VALIDATE_EMAIL) ? Result::ok(['email' => strtolower($row['email'])]) : Result::fail("Invalid email for {$key}"); // mapItems: returns array of Results (one per item) $results = Result::mapItems($rows, $validator); // ['user1' => ok(...), 'user2' => fail(...), 'user3' => ok(...)] // mapAll: fail-fast aggregate $result = Result::mapAll($rows, $validator); // Result: fail('Invalid email for user2') - stops at first failure // mapCollectErrors: processes all, collects keyed errors $result = Result::mapCollectErrors($rows, $validator); // Result: fail(['user2' => 'Invalid email for user2']) // Or on full success: ok(['user1' => [...], 'user3' => [...]]) ``` -------------------------------- ### Output Transformers for Result Objects (PHP) Source: https://context7.com/maxiviper117/result-flow/llms.txt Convert Result objects to various output formats suitable for API responses and debugging. Supports conversion to arrays, JSON, and XML, with options for pretty printing and sanitization. ```php use Maxiviper117\ResultFlow\Result; $result = Result::ok(['id' => 1, 'name' => 'John'], ['request_id' => 'r-1']); // Raw array $array = $result->toArray(); // ['ok' => true, 'value' => [...], 'error' => null, 'meta' => [...]] // Debug-safe array (sanitizes sensitive data) $debug = $result->toDebugArray(); // ['ok' => true, 'value_type' => 'array', 'error_type' => null, 'error_message' => null, 'meta' => [...]] // JSON $json = $result->toJson(JSON_PRETTY_PRINT); // XML $xml = $result->toXml('response'); // HTTP Response (Laravel-compatible when available) return $result->toResponse(); // Returns JsonResponse in Laravel, array otherwise ``` -------------------------------- ### Retry Deferred Operations Source: https://github.com/maxiviper117/result-flow/blob/main/README.md Configures a deferred operation to retry a specified number of times with optional exponential backoff. ```php use Maxiviper117\ResultFlow\Result; $result = Result::retryDefer( 3, fn () => callExternalApi($payload), delay: 100, exponential: true, ); ``` -------------------------------- ### Retry Failed Operations with retry and retryDefer - PHP Source: https://context7.com/maxiviper117/result-flow/llms.txt Methods for retrying operations that may fail transiently. `retry` supports a fixed number of attempts with optional exponential backoff delays. `retryDefer` normalizes callback output similarly to `defer`. An advanced fluent builder is also available for more complex retry configurations. ```php use Maxiviper117\ResultFlow\Result; // Simple retry with exponential backoff $result = Result::retry( times: 3, fn: fn () => callExternalApi($payload), delay: 100, // 100ms base delay exponential: true // 100ms, 200ms, 400ms... ); // retryDefer: normalizes callback output like defer() $attempt = 0; $result = Result::retryDefer( times: 3, fn: function () use (&$attempt) { $attempt++; if ($attempt < 3) { throw new RuntimeException("Attempt {$attempt} failed"); } return ['success' => true, 'attempt' => $attempt]; }, delay: 50, exponential: true )->otherwise(fn ($e) => Result::fail("All retries exhausted: {$e}")); // Advanced retry with fluent builder $result = Result::retrier() ->maxAttempts(5) ->delay(100) ->exponential(true) ->jitter(50) // Add randomness to prevent thundering herd ->attempt(fn () => unreliableOperation()); ``` -------------------------------- ### Handle Failure Branch with otherwise Source: https://context7.com/maxiviper117/result-flow/llms.txt Processes the failure branch of a result. It allows for recovery by returning a success result, transforming the error into a new failure, or returning a plain value that is automatically wrapped as a success. ```php use Maxiviper117\ResultFlow\Result; // Recovery: return ok() to switch to success branch $result = Result::fail('Primary failed') ->otherwise(fn ($error, $meta) => Result::ok(['fallback' => true, 'original_error' => $error])); // Transformation: return fail() to keep failing with different error $result = Result::fail('DB connection timeout', ['operation' => 'user.fetch']) ->otherwise(fn ($error, $meta) => Result::fail([ 'code' => 'SERVICE_UNAVAILABLE', 'message' => $error, 'operation' => $meta['operation'] ], $meta)); // Plain value returned recovers to success $result = Result::fail('Missing data') ->otherwise(fn () => ['default' => true]); ``` -------------------------------- ### Validate Success Values with ensure Source: https://context7.com/maxiviper117/result-flow/llms.txt Validates success values within a chain using a predicate. If the predicate returns false, the result is converted to a failure, supporting both static messages and dynamic error factories. ```php use Maxiviper117\ResultFlow\Result; $result = Result::ok(['total' => 150], ['request_id' => 'r-1']) ->ensure(fn (array $order) => $order['total'] > 0, 'Order total must be positive') ->ensure(fn (array $order) => $order['total'] <= 1000, 'Order total exceeds limit'); // With dynamic error factory $result = Result::ok(['email' => 'invalid']) ->ensure( fn ($data) => filter_var($data['email'], FILTER_VALIDATE_EMAIL), fn ($data) => "Invalid email: {$data['email']}" ); ``` -------------------------------- ### Side Effects with Tap Methods in Result Flow (PHP) Source: https://context7.com/maxiviper117/result-flow/llms.txt Inspect or perform side effects on results without modifying the chain using tap methods. These methods allow logging, debugging, or triggering other actions on both success and failure branches of a Result. ```php use Maxiviper117\ResultFlow\Result; $result = Result::ok(['user_id' => 123]) // Tap both branches ->tap(fn ($value, $error, $meta) => logger()->debug('Result state', 'ok' => $value !== null, 'meta' => $meta ])) // Tap success only ->onSuccess(fn ($value, $meta) => logger()->info('Success', ['value' => $value])) ->inspect(fn ($value) => cache()->set('last_user', $value)) // Alias for onSuccess // Tap failure only ->onFailure(fn ($error, $meta) => logger()->warning('Failure', ['error' => $error])) ->inspectError(fn ($error) => metrics()->increment('errors')); // Alias for onFailure ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.