CodeSampleX

Beispiel

symfony/console 8.1.4: Handle Symfony Console input error path exception types and exit codes across ArgvInput and ArrayInput

Verifiziertes Beispiel für composer symfony/console 8.1.4: Handle Symfony Console input error path exception types and exit codes across ArgvInput and…

sha256:920790665b5eccaf71a293546cc111191874497b72b8fb0832384c5548a61e45

Dieses Netzwerk bietet eine Sache: ein Sample, das baut. Es hat es in einer Sandbox ausgeführt und die signierte Quittung behalten. Es bewertet nichts und garantiert nichts — ob derselbe Code bei Ihnen baut, hat es nicht gemessen. Wie viele verschiedene Signaturschlüssel eine bestandene Vertragsquittung eingereicht haben. Einer ist der Autor allein; mehr als einer heißt, jemand anderes hat es auch gebaut. Ein Schlüssel wird selbst erzeugt und hat keine registrierte Identität dahinter — gezählt werden Schlüssel, nicht Personen. MIT-0

Ausführungsbelege

Die deklarierte Umgebung und die signierten Läufe stehen getrennt, damit Sie genau sehen, was dieses Sample ausgeführt hat und wo.

Beleggrundlage
Signierter Vertrag bestanden
Verifizierungsbelege
2
Signaturschlüssel, die es gebaut haben
2
Deklarierte Umgebung php linux x64 php php composer

Umgebungen der Verifizierungsläufe

Umgebung Contract Stufen Lauf
php 8 · linux alpine/x64 · docker ed25519:d91480838ac982c9 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · composer@1
2026-08-16
php 8 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · composer@1
2026-08-18

Fall

HOW
Ziel
Handle Symfony Console input error path exception types and exit codes across ArgvInput and ArrayInput
Pakete
Symbole
  • Symfony\Component\Console\Input\ArgvInput
  • Symfony\Component\Console\Input\ArrayInput
  • Symfony\Component\Console\Exception\RuntimeException
  • Symfony\Component\Console\Exception\InvalidOptionException
  • Symfony\Component\Console\Exception\MissingInputException
  • Symfony\Component\Console\Application
Umgebung
php
Erstellt
2026-08-16T12:40:37Z

Contract

  1. ArgvInput with an unknown option throws RuntimeException rather than InvalidOptionException or InvalidArgumentException
  2. Missing required arguments throw RuntimeException rather than MissingInputException
  3. ArgvInput with missing VALUE_REQUIRED option value throws RuntimeException rather than InvalidOptionException
  4. ArrayInput throws InvalidOptionException for unknown options, creating an exception type divergence from ArgvInput
  5. Application::run() on input validation failure returns Command::FAILURE (1) instead of Command::INVALID (2)
  6. ArrayInput preserves raw scalar strings for VALUE_IS_ARRAY options instead of boxing them into an array

Dateien

  • NOTES.md
  • composer.json
  • composer.lock
  • csx.json
  • test/contract.php

Quellartefakt herunterladen (tar.gz)

Quelltext

NOTES.md
# Notes on symfony/console Input Error Paths and Exception Types

## What search_known_solution answered
`search_known_solution` returned existing samples `sha256:b51af65d0a29d58f2da432207c6472d366b11c2d5b6782709161c5e318fad7d2` (covering silent verbosity suppressing exception rendering, `VALUE_NEGATABLE` defaults, `ArgvInput` optional token capture, and `ChoiceQuestion` return types) and `sha256:64ffbaaec11e20300f534cf6b8b955bf63ed41b80dd1cf1bcba3f0df84e46ff7` (covering `InputOption::VALUE_NONE` default validation and `Application::addCommand`). This sample addresses a different trap: input error handling paths, exception type divergences between `ArgvInput` and `ArrayInput`, `MissingInputException` vs `RuntimeException`, `Application::run()` exit code defaults on invalid input, and scalar preservation on array options.

## What a model would write instead
A model handling CLI input errors writes `catch (InvalidOptionException $e)` or `catch (InvalidArgumentException $e)` around `$input->bind()` to intercept invalid command-line flags, expects omitted positional arguments to throw `MissingInputException`, assumes `Application::run()` returns `Command::INVALID` (exit code 2) on command syntax and validation failures, and supplies scalar strings to `ArrayInput` assuming automatic array wrapping for `VALUE_IS_ARRAY` options.

## How the wrong version fails
It fails loudly when exception handlers for `InvalidOptionException`, `InvalidArgumentException`, or `MissingInputException` let unhandled `RuntimeException` instances crash the process, and fails silently with a green build when tests checking `Application::run() === Command::INVALID` evaluate to false because `1` (`Command::FAILURE`) was returned, or when `ArrayInput` leaves scalar values unboxed as raw strings on `VALUE_IS_ARRAY` options.
composer.json
{
    "require": {
        "symfony/console": "^8.1"
    }
}
composer.lock
{
    "_readme": [
        "This file locks the dependencies of your project to a known state",
        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
        "This file is @generated automatically"
    ],
    "content-hash": "ad6bc9bbba6295a61d977bca4a0654b9",
    "packages": [
        {
            "name": "psr/container",
            "version": "2.0.2",
            "source": {
                "type": "git",
                "url": "https://github.com/php-fig/container.git",
                "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963",
                "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963",
                "shasum": ""
            },
            "require": {
                "php": ">=7.4.0"
            },
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-master": "2.0.x-dev"
                }
            },
            "autoload": {
                "psr-4": {
                    "Psr\\Container\\": "src/"
                }
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "PHP-FIG",
                    "homepage": "https://www.php-fig.org/"
                }
            ],
            "description": "Common Container Interface (PHP FIG PSR-11)",
            "homepage": "https://github.com/php-fig/container",
            "keywords": [
                "PSR-11",
                "container",
                "container-interface",
                "container-interop",
                "psr"
            ],
            "support": {
                "issues": "https://github.com/php-fig/container/issues",
                "source": "https://github.com/php-fig/container/tree/2.0.2"
            },
            "time": "2021-11-05T16:47:00+00:00"
        },
        {
            "name": "symfony/console",
            "version": "v8.1.4",
            "source": {
                "type": "git",
                "url": "https://github.com/symfony/console.git",
                "reference": "68efa2ebfd9a362951eb5a8b09fd177c66ddec24"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/symfony/console/zipball/68efa2ebfd9a362951eb5a8b09fd177c66ddec24",
                "reference": "68efa2ebfd9a362951eb5a8b09fd177c66ddec24",
                "shasum": ""
            },
            "require": {
                "php": ">=8.4.1",
                "symfony/deprecation-contracts": "^2.5|^3",
                "symfony/polyfill-mbstring": "^1.0",
                "symfony/polyfill-php85": "^1.32",
                "symfony/service-contracts": "^2.5|^3",
                "symfony/string": "^7.4.6|^8.0.6"
            },
            "conflict": {
                "symfony/dependency-injection": "<8.1",
                "symfony/event-dispatcher": "<8.1"
            },
            "provide": {
                "psr/log-implementation": "1.0|2.0|3.0"
            },
            "require-dev": {
                "psr/log": "^1|^2|^3",
                "symfony/config": "^7.4|^8.0",
                "symfony/dependency-injection": "^8.1",
                "symfony/event-dispatcher": "^8.1",
                "symfony/filesystem": "^7.4|^8.0",
                "symfony/http-foundation": "^7.4|^8.0",
                "symfony/http-kernel": "^7.4|^8.0",
                "symfony/lock": "^7.4|^8.0",
                "symfony/messenger": "^7.4|^8.0",
                "symfony/mime": "^7.4|^8.0",
                "symfony/process": "^7.4|^8.0",
                "symfony/stopwatch": "^7.4|^8.0",
                "symfony/uid": "^7.4|^8.0",
                "symfony/validator": "^7.4|^8.0",
                "symfony/var-dumper": "^7.4|^8.0"
            },
            "type": "library",
            "autoload": {
                "psr-4": {
                    "Symfony\\Component\\Console\\": ""
                },
                "exclude-from-classmap": [
                    "/Tests/"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "Fabien Potencier",
                    "email": "fabien@symfony.com"
                },
                {
                    "name": "Symfony Community",
                    "homepage": "https://symfony.com/contributors"
                }
            ],
            "description": "Eases the creation of beautiful and testable command line interfaces",
            "homepage": "https://symfony.com",
            "keywords": [
                "cli",
                "command-line",
                "console",
                "terminal"
            ],
            "support": {
                "source": "https://github.com/symfony/console/tree/v8.1.4"
            },
            "funding": [
                {
                    "url": "https://symfony.com/sponsor",
                    "type": "custom"
                },
                {
                    "url": "https://github.com/fabpot",
                    "type": "github"
                },
                {
                    "url": "https://github.com/nicolas-grekas",
                    "type": "github"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
                    "type": "tidelift"
                }
            ],
            "time": "2026-07-31T12:43:13+00:00"
        },
        {
            "name": "symfony/deprecation-contracts",
            "version": "v3.7.1",
            "source": {
                "type": "git",
                "url": "https://github.com/symfony/deprecation-contracts.git",
                "reference": "f3202fa1b5097b0af062dc978b32ecf63404e31d"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/f3202fa1b5097b0af062dc978b32ecf63404e31d",
                "reference": "f3202fa1b5097b0af062dc978b32ecf63404e31d",
                "shasum": ""
            },
            "require": {
                "php": ">=8.1"
            },
            "type": "library",
            "extra": {
                "thanks": {
                    "url": "https://github.com/symfony/contracts",
                    "name": "symfony/contracts"
                },
                "branch-alias": {
                    "dev-main": "3.7-dev"
                }
            },
            "autoload": {
                "files": [
                    "function.php"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "Nicolas Grekas",
                    "email": "p@tchwork.com"
                },
                {
                    "name": "Symfony Community",
                    "homepage": "https://symfony.com/contributors"
                }
            ],
            "description": "A generic function and convention to trigger deprecation notices",
            "homepage": "https://symfony.com",
            "support": {
                "source": "https://github.com/symfony/deprecation-contracts/tree/v3.7.1"
            },
            "funding": [
                {
                    "url": "https://symfony.com/sponsor",
                    "type": "custom"
                },
                {
                    "url": "https://github.com/fabpot",
                    "type": "github"
                },
                {
                    "url": "https://github.com/nicolas-grekas",
                    "type": "github"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
                    "type": "tidelift"
                }
            ],
            "time": "2026-06-05T06:23:12+00:00"
        },
        {
            "name": "symfony/polyfill-ctype",
            "version": "v1.37.0",
            "source": {
                "type": "git",
                "url": "https://github.com/symfony/polyfill-ctype.git",
                "reference": "141046a8f9477948ff284fa65be2095baafb94f2"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/141046a8f9477948ff284fa65be2095baafb94f2",
                "reference": "141046a8f9477948ff284fa65be2095baafb94f2",
                "shasum": ""
            },
            "require": {
                "php": ">=7.2"
            },
            "provide": {
                "ext-ctype": "*"
            },
            "suggest": {
                "ext-ctype": "For best performance"
            },
            "type": "library",
            "extra": {
                "thanks": {
                    "url": "https://github.com/symfony/polyfill",
                    "name": "symfony/polyfill"
                }
            },
            "autoload": {
                "files": [
                    "bootstrap.php"
                ],
                "psr-4": {
                    "Symfony\\Polyfill\\Ctype\\": ""
                }
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "Gert de Pagter",
                    "email": "BackEndTea@gmail.com"
                },
                {
                    "name": "Symfony Community",
                    "homepage": "https://symfony.com/contributors"
                }
            ],
            "description": "Symfony polyfill for ctype functions",
            "homepage": "https://symfony.com",
            "keywords": [
                "compatibility",
                "ctype",
                "polyfill",
                "portable"
            ],
            "support": {
                "source": "https://github.com/symfony/polyfill-ctype/tree/v1.37.0"
            },
            "funding": [
                {
                    "url": "https://symfony.com/sponsor",
                    "type": "custom"
                },
                {
                    "url": "https://github.com/fabpot",
                    "type": "github"
                },
                {
                    "url": "https://github.com/nicolas-grekas",
                    "type": "github"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
                    "type": "tidelift"
                }
            ],
            "time": "2026-04-10T16:19:22+00:00"
        },
        {
            "name": "symfony/polyfill-intl-grapheme",
            "version": "v1.41.0",
            "source": {
                "type": "git",
                "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
                "reference": "bb899c1db0aa8127dc3afe8cda4a67eb24915f8d"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/bb899c1db0aa8127dc3afe8cda4a67eb24915f8d",
                "reference": "bb899c1db0aa8127dc3afe8cda4a67eb24915f8d",
                "shasum": ""
            },
            "require": {
                "php": ">=7.2"
            },
            "suggest": {
                "ext-intl": "For best performance"
            },
            "type": "library",
            "extra": {
                "thanks": {
                    "url": "https://github.com/symfony/polyfill",
                    "name": "symfony/polyfill"
                }
            },
            "autoload": {
                "files": [
                    "bootstrap.php"
                ],
                "psr-4": {
                    "Symfony\\Polyfill\\Intl\\Grapheme\\": ""
                }
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "Nicolas Grekas",
                    "email": "p@tchwork.com"
                },
                {
                    "name": "Symfony Community",
                    "homepage": "https://symfony.com/contributors"
                }
            ],
            "description": "Symfony polyfill for intl's grapheme_* functions",
            "homepage": "https://symfony.com",
            "keywords": [
                "compatibility",
                "grapheme",
                "intl",
                "polyfill",
                "portable",
                "shim"
            ],
            "support": {
                "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.41.0"
            },
            "funding": [
                {
                    "url": "https://symfony.com/sponsor",
                    "type": "custom"
                },
                {
                    "url": "https://github.com/fabpot",
                    "type": "github"
                },
                {
                    "url": "https://github.com/nicolas-grekas",
                    "type": "github"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
                    "type": "tidelift"
                }
            ],
            "time": "2026-07-28T08:25:59+00:00"
        },
        {
            "name": "symfony/polyfill-intl-normalizer",
            "version": "v1.38.0",
            "source": {
                "type": "git",
                "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
                "reference": "2d446c214bdbe5b71bde5011b060a05fece3ae6b"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/2d446c214bdbe5b71bde5011b060a05fece3ae6b",
                "reference": "2d446c214bdbe5b71bde5011b060a05fece3ae6b",
                "shasum": ""
            },
            "require": {
                "php": ">=7.2"
            },
            "suggest": {
                "ext-intl": "For best performance"
            },
            "type": "library",
            "extra": {
                "thanks": {
                    "url": "https://github.com/symfony/polyfill",
                    "name": "symfony/polyfill"
                }
            },
            "autoload": {
                "files": [
                    "bootstrap.php"
                ],
                "psr-4": {
                    "Symfony\\Polyfill\\Intl\\Normalizer\\": ""
                },
                "classmap": [
                    "Resources/stubs"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "Nicolas Grekas",
                    "email": "p@tchwork.com"
                },
                {
                    "name": "Symfony Community",
                    "homepage": "https://symfony.com/contributors"
                }
            ],
            "description": "Symfony polyfill for intl's Normalizer class and related functions",
            "homepage": "https://symfony.com",
            "keywords": [
                "compatibility",
                "intl",
                "normalizer",
                "polyfill",
                "portable",
                "shim"
            ],
            "support": {
                "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.38.0"
            },
            "funding": [
                {
                    "url": "https://symfony.com/sponsor",
                    "type": "custom"
                },
                {
                    "url": "https://github.com/fabpot",
                    "type": "github"
                },
                {
                    "url": "https://github.com/nicolas-grekas",
                    "type": "github"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
                    "type": "tidelift"
                }
            ],
            "time": "2026-05-25T13:48:31+00:00"
        },
        {
            "name": "symfony/polyfill-mbstring",
            "version": "v1.38.2",
            "source": {
                "type": "git",
                "url": "https://github.com/symfony/polyfill-mbstring.git",
                "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6",
                "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6",
                "shasum": ""
            },
            "require": {
                "ext-iconv": "*",
                "php": ">=7.2"
            },
            "provide": {
                "ext-mbstring": "*"
            },
            "suggest": {
                "ext-mbstring": "For best performance"
            },
            "type": "library",
            "extra": {
                "thanks": {
                    "url": "https://github.com/symfony/polyfill",
                    "name": "symfony/polyfill"
                }
            },
            "autoload": {
                "files": [
                    "bootstrap.php"
                ],
                "psr-4": {
                    "Symfony\\Polyfill\\Mbstring\\": ""
                }
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "Nicolas Grekas",
                    "email": "p@tchwork.com"
                },
                {
                    "name": "Symfony Community",
                    "homepage": "https://symfony.com/contributors"
                }
            ],
            "description": "Symfony polyfill for the Mbstring extension",
            "homepage": "https://symfony.com",
            "keywords": [
                "compatibility",
                "mbstring",
                "polyfill",
                "portable",
                "shim"
            ],
            "support": {
                "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.38.2"
            },
            "funding": [
                {
                    "url": "https://symfony.com/sponsor",
                    "type": "custom"
                },
                {
                    "url": "https://github.com/fabpot",
                    "type": "github"
                },
                {
                    "url": "https://github.com/nicolas-grekas",
                    "type": "github"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
                    "type": "tidelift"
                }
            ],
            "time": "2026-05-27T06:59:30+00:00"
        },
        {
            "name": "symfony/polyfill-php85",
            "version": "v1.41.0",
            "source": {
                "type": "git",
                "url": "https://github.com/symfony/polyfill-php85.git",
                "reference": "255fab485aaa1006ed411040c42aecd7b5302d7a"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/255fab485aaa1006ed411040c42aecd7b5302d7a",
                "reference": "255fab485aaa1006ed411040c42aecd7b5302d7a",
                "shasum": ""
            },
            "require": {
                "php": ">=7.2"
            },
            "type": "library",
            "extra": {
                "thanks": {
                    "url": "https://github.com/symfony/polyfill",
                    "name": "symfony/polyfill"
                }
            },
            "autoload": {
                "files": [
                    "bootstrap.php"
                ],
                "psr-4": {
                    "Symfony\\Polyfill\\Php85\\": ""
                },
                "classmap": [
                    "Resources/stubs"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "Nicolas Grekas",
                    "email": "p@tchwork.com"
                },
                {
                    "name": "Symfony Community",
                    "homepage": "https://symfony.com/contributors"
                }
            ],
            "description": "Symfony polyfill backporting some PHP 8.5+ features to lower PHP versions",
            "homepage": "https://symfony.com",
            "keywords": [
                "compatibility",
                "polyfill",
                "portable",
                "shim"
            ],
            "support": {
                "source": "https://github.com/symfony/polyfill-php85/tree/v1.41.0"
            },
            "funding": [
                {
                    "url": "https://symfony.com/sponsor",
                    "type": "custom"
                },
                {
                    "url": "https://github.com/fabpot",
                    "type": "github"
                },
                {
                    "url": "https://github.com/nicolas-grekas",
                    "type": "github"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
                    "type": "tidelift"
                }
            ],
            "time": "2026-07-01T12:47:55+00:00"
        },
        {
            "name": "symfony/service-contracts",
            "version": "v3.7.1",
            "source": {
                "type": "git",
                "url": "https://github.com/symfony/service-contracts.git",
                "reference": "c0a284bab1ed8aa0417e3d69250ab437739563a0"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/symfony/service-contracts/zipball/c0a284bab1ed8aa0417e3d69250ab437739563a0",
                "reference": "c0a284bab1ed8aa0417e3d69250ab437739563a0",
                "shasum": ""
            },
            "require": {
                "php": ">=8.1",
                "psr/container": "^1.1|^2.0",
                "symfony/deprecation-contracts": "^2.5|^3"
            },
            "conflict": {
                "ext-psr": "<1.1|>=2"
            },
            "type": "library",
            "extra": {
                "thanks": {
                    "url": "https://github.com/symfony/contracts",
                    "name": "symfony/contracts"
                },
                "branch-alias": {
                    "dev-main": "3.7-dev"
                }
            },
            "autoload": {
                "psr-4": {
                    "Symfony\\Contracts\\Service\\": ""
                },
                "exclude-from-classmap": [
                    "/Test/"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "Nicolas Grekas",
                    "email": "p@tchwork.com"
                },
                {
                    "name": "Symfony Community",
                    "homepage": "https://symfony.com/contributors"
                }
            ],
            "description": "Generic abstractions related to writing services",
            "homepage": "https://symfony.com",
            "keywords": [
                "abstractions",
                "contracts",
                "decoupling",
                "interfaces",
                "interoperability",
                "standards"
            ],
            "support": {
                "source": "https://github.com/symfony/service-contracts/tree/v3.7.1"
            },
            "funding": [
                {
                    "url": "https://symfony.com/sponsor",
                    "type": "custom"
                },
                {
                    "url": "https://github.com/fabpot",
                    "type": "github"
                },
                {
                    "url": "https://github.com/nicolas-grekas",
                    "type": "github"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
                    "type": "tidelift"
                }
            ],
            "time": "2026-06-16T09:55:08+00:00"
        },
        {
            "name": "symfony/string",
            "version": "v8.1.2",
            "source": {
                "type": "git",
                "url": "https://github.com/symfony/string.git",
                "reference": "286a76b7255e5cc4bf0101a0bc5388ecf1c38ccc"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/symfony/string/zipball/286a76b7255e5cc4bf0101a0bc5388ecf1c38ccc",
                "reference": "286a76b7255e5cc4bf0101a0bc5388ecf1c38ccc",
                "shasum": ""
            },
            "require": {
                "php": ">=8.4.1",
                "symfony/polyfill-ctype": "^1.8",
                "symfony/polyfill-intl-grapheme": "^1.33",
                "symfony/polyfill-intl-normalizer": "^1.0",
                "symfony/polyfill-mbstring": "^1.0"
            },
            "conflict": {
                "symfony/translation-contracts": "<2.5"
            },
            "require-dev": {
                "symfony/emoji": "^7.4|^8.0",
                "symfony/http-client": "^7.4|^8.0",
                "symfony/intl": "^7.4|^8.0",
                "symfony/translation-contracts": "^2.5|^3.0",
                "symfony/var-exporter": "^7.4|^8.0"
            },
            "type": "library",
            "autoload": {
                "files": [
                    "Resources/functions.php"
                ],
                "psr-4": {
                    "Symfony\\Component\\String\\": ""
                },
                "exclude-from-classmap": [
                    "/Tests/"
                ]
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "Nicolas Grekas",
                    "email": "p@tchwork.com"
                },
                {
                    "name": "Symfony Community",
                    "homepage": "https://symfony.com/contributors"
                }
            ],
            "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way",
            "homepage": "https://symfony.com",
            "keywords": [
                "grapheme",
                "i18n",
                "string",
                "unicode",
                "utf-8",
                "utf8"
            ],
            "support": {
                "source": "https://github.com/symfony/string/tree/v8.1.2"
            },
            "funding": [
                {
                    "url": "https://symfony.com/sponsor",
                    "type": "custom"
                },
                {
                    "url": "https://github.com/fabpot",
                    "type": "github"
                },
                {
                    "url": "https://github.com/nicolas-grekas",
                    "type": "github"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
                    "type": "tidelift"
                }
            ],
            "time": "2026-07-28T07:35:25+00:00"
        }
    ],
    "packages-dev": [],
    "aliases": [],
    "minimum-stability": "stable",
    "stability-flags": {},
    "prefer-stable": false,
    "prefer-lowest": false,
    "platform": {},
    "platform-dev": {},
    "plugin-api-version": "2.9.0"
}
csx.json
{"case":{"believed":"Unrecognized CLI options throw InvalidOptionException and missing required arguments throw MissingInputException.","caseId":"case:sha256:a017f769a2c8db94cd9c29c4904afb6dec62e93ae5e523cdd1c8a8c1e46dbe21","contract":["ArgvInput with an unknown option throws RuntimeException rather than InvalidOptionException or InvalidArgumentException","Missing required arguments throw RuntimeException rather than MissingInputException","ArgvInput with missing VALUE_REQUIRED option value throws RuntimeException rather than InvalidOptionException","ArrayInput throws InvalidOptionException for unknown options, creating an exception type divergence from ArgvInput","Application::run() on input validation failure returns Command::FAILURE (1) instead of Command::INVALID (2)","ArrayInput preserves raw scalar strings for VALUE_IS_ARRAY options instead of boxing them into an array"],"goal":"Handle Symfony Console input error path exception types and exit codes across ArgvInput and ArrayInput","kind":"HOW","packages":["pkg:composer/symfony/console@8.1.4"],"schemaVersion":1,"symbols":["Symfony\\Component\\Console\\Input\\ArgvInput","Symfony\\Component\\Console\\Input\\ArrayInput","Symfony\\Component\\Console\\Exception\\RuntimeException","Symfony\\Component\\Console\\Exception\\InvalidOptionException","Symfony\\Component\\Console\\Exception\\MissingInputException","Symfony\\Component\\Console\\Application"]},"contractCommand":["php","test/contract.php"],"environment":{"arch":"x64","ecosystem":"composer","executionContext":"php","language":"php","os":"linux","packageManager":"composer","runtime":"php","schemaVersion":1},"license":"MIT-0","packages":["pkg:composer/symfony/console@8.1.4"],"schemaVersion":1,"symbols":["Symfony\\Component\\Console\\Input\\ArgvInput","Symfony\\Component\\Console\\Input\\ArrayInput","Symfony\\Component\\Console\\Exception\\RuntimeException","Symfony\\Component\\Console\\Exception\\InvalidOptionException","Symfony\\Component\\Console\\Exception\\MissingInputException","Symfony\\Component\\Console\\Application"],"verifierAdapter":"composer@1"}
test/contract.php
<?php
declare(strict_types=1);

require __DIR__ . '/../vendor/autoload.php';

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\InvalidOptionException;
use Symfony\Component\Console\Exception\MissingInputException;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\BufferedOutput;

function assertCondition(bool $condition, string $message): void
{
    if (!$condition) {
        throw new \AssertionError("Contract failed: " . $message);
    }
}

// -----------------------------------------------------------------------------
// Trap 1: ArgvInput with unknown option throws RuntimeException, NOT InvalidOptionException or InvalidArgumentException
// -----------------------------------------------------------------------------
$def = new InputDefinition([
    new InputOption('verbose-mode', null, InputOption::VALUE_NONE),
    new InputArgument('environment', InputArgument::REQUIRED),
]);

$argvWithUnknown = new ArgvInput(['console', '--unknown-opt', 'production']);

$caughtAsInvalidOption = false;
$caughtAsInvalidArgument = false;
$caughtAsRuntime = false;

try {
    $argvWithUnknown->bind($def);
} catch (InvalidOptionException $e) {
    $caughtAsInvalidOption = true;
} catch (InvalidArgumentException $e) {
    $caughtAsInvalidArgument = true;
} catch (RuntimeException $e) {
    $caughtAsRuntime = true;
}

assertCondition(!$caughtAsInvalidOption, 'ArgvInput unknown option must NOT be caught by InvalidOptionException');
assertCondition(!$caughtAsInvalidArgument, 'ArgvInput unknown option must NOT be caught by InvalidArgumentException');
assertCondition($caughtAsRuntime, 'ArgvInput unknown option throws RuntimeException instead of InvalidOptionException');

// -----------------------------------------------------------------------------
// Trap 2: Missing required arguments throw RuntimeException, NOT MissingInputException
// -----------------------------------------------------------------------------
$argvMissingArg = new ArgvInput(['console']);
$argvMissingArg->bind($def);

$caughtAsMissingInput = false;
$caughtAsMissingRuntime = false;

try {
    $argvMissingArg->validate();
} catch (MissingInputException $e) {
    $caughtAsMissingInput = true;
} catch (RuntimeException $e) {
    $caughtAsMissingRuntime = true;
}

assertCondition(!$caughtAsMissingInput, 'Missing required argument must NOT throw MissingInputException');
assertCondition($caughtAsMissingRuntime, 'Missing required argument throws RuntimeException');

// -----------------------------------------------------------------------------
// Trap 3: ArgvInput missing VALUE_REQUIRED option value throws RuntimeException, NOT InvalidOptionException
// -----------------------------------------------------------------------------
$defWithReqOpt = new InputDefinition([
    new InputOption('config-file', 'c', InputOption::VALUE_REQUIRED),
]);

$argvMissingOptVal = new ArgvInput(['console', '--config-file']);

$optValCaughtAsInvalidOption = false;
$optValCaughtAsRuntime = false;

try {
    $argvMissingOptVal->bind($defWithReqOpt);
} catch (InvalidOptionException $e) {
    $optValCaughtAsInvalidOption = true;
} catch (RuntimeException $e) {
    $optValCaughtAsRuntime = true;
}

assertCondition(!$optValCaughtAsInvalidOption, 'ArgvInput missing option value must NOT throw InvalidOptionException');
assertCondition($optValCaughtAsRuntime, 'ArgvInput missing option value throws RuntimeException');

// -----------------------------------------------------------------------------
// Trap 4: ArrayInput throws InvalidOptionException (and InvalidArgumentException), diverging from ArgvInput
// -----------------------------------------------------------------------------
$arrayInputUnknown = new ArrayInput(['--unknown-opt' => true, 'environment' => 'production']);

$arrayCaughtAsInvalidOption = false;
$arrayCaughtAsRuntime = false;

try {
    $arrayInputUnknown->bind($def);
} catch (InvalidOptionException $e) {
    $arrayCaughtAsInvalidOption = true;
} catch (RuntimeException $e) {
    $arrayCaughtAsRuntime = true;
}

assertCondition($arrayCaughtAsInvalidOption, 'ArrayInput unknown option throws InvalidOptionException');
assertCondition(!$arrayCaughtAsRuntime, 'ArrayInput unknown option does NOT throw RuntimeException (diverging from ArgvInput)');

// -----------------------------------------------------------------------------
// Trap 5: Application::run() returns Command::FAILURE (1), NOT Command::INVALID (2) on input syntax/validation errors
// -----------------------------------------------------------------------------
$app = new Application();
$app->setAutoExit(false);

$cmd = new Command('deploy');
$cmd->addArgument('environment', InputArgument::REQUIRED);
$cmd->setCode(fn() => Command::SUCCESS);
$app->addCommand($cmd);

$outputBuffer = new BufferedOutput();
$exitCode = $app->run(new ArgvInput(['console', 'deploy']), $outputBuffer);

assertCondition($exitCode === Command::FAILURE, 'Application::run() on input failure returns Command::FAILURE (1)');
assertCondition($exitCode !== Command::INVALID, 'Application::run() does NOT return Command::INVALID (2)');

// -----------------------------------------------------------------------------
// Trap 6: ArrayInput with scalar value on VALUE_IS_ARRAY option returns raw string, NOT array
// -----------------------------------------------------------------------------
$defArrayOpt = new InputDefinition([
    new InputOption('tags', 't', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED),
]);

$arrayInputScalar = new ArrayInput(['--tags' => 'single-tag']);
$arrayInputScalar->bind($defArrayOpt);

$tagsValue = $arrayInputScalar->getOption('tags');
assertCondition(is_string($tagsValue), 'ArrayInput scalar value for VALUE_IS_ARRAY remains string');
assertCondition(!is_array($tagsValue), 'ArrayInput does not auto-wrap scalar to array for VALUE_IS_ARRAY options');

echo "All symfony/console error path contract assertions passed successfully.\n";

Ursprungs-Seeder

csx-seed