{"record":{"id":"e3993bf6adc1bde8","repo":"phar-io/manifest","slug":"t-getmessage","errorCode":null,"errorMessage":"$t->getMessage()","messagePattern":"\\$t->getMessage\\(\\)","errorType":"exception","errorClass":"ManifestDocumentException","httpStatus":null,"severity":"error","filePath":"src/xml/ManifestDocument.php","lineNumber":52,"sourceCode":"            );\n        }\n\n        return self::fromString(\n            file_get_contents($filename)\n        );\n    }\n\n    public static function fromString(string $xmlString): ManifestDocument {\n        $prev = libxml_use_internal_errors(true);\n        libxml_clear_errors();\n\n        try {\n            $dom = new DOMDocument();\n            $dom->loadXML($xmlString);\n            $errors = libxml_get_errors();\n            libxml_use_internal_errors($prev);\n        } catch (Throwable $t) {\n            throw new ManifestDocumentException($t->getMessage(), 0, $t);\n        }\n\n        if (count($errors) !== 0) {\n            throw new ManifestDocumentLoadingException($errors);\n        }\n\n        return new self($dom);\n    }\n\n    private function __construct(DOMDocument $dom) {\n        $this->ensureCorrectDocumentType($dom);\n\n        $this->dom = $dom;\n    }\n\n    public function getContainsElement(): ContainsElement {\n        return new ContainsElement(\n            $this->fetchElementByName('contains')","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/phar-io/manifest/blob/c581d4941e196459bf76c945a8ca922963a66708/src/xml/ManifestDocument.php#L34-L70","documentation":"ManifestDocument::fromString wraps any Throwable raised while loading the XML string into a ManifestDocumentException whose message is the underlying exception's message (in PHP, DOMDocument::loadXML emits a warning/notice rather than throwing, so this catch rarely fires; the message is whatever the native DOM/libxml layer threw). It signals that the string could not be turned into a DOMDocument. The library re-throws with code 0 and the original as previous exception.","triggerScenarios":"Calling ManifestDocument::fromString() with input that makes DOMDocument construction/loading throw — e.g. an empty string passed to loadXML, or a PHP level failure inside the try block. Note empty input typically surfaces as libxml errors -> ManifestDocumentLoadingException instead; this catch handles Throwable cases.","commonSituations":"Passing null/empty output from file_get_contents to fromString because the manifest file path was wrong; feeding non-XML content (HTML, binary, truncated download); encoding problems in the manifest string.","solutions":["Print the previous exception via $e->getPrevious() to see the underlying libxml/DOM error","Verify the input string is non-empty and well-formed XML before calling fromString","Ensure the file was read successfully (check file_get_contents return value !== false)","Use fromFile() instead of manually reading then fromString()"],"exampleFix":"// before\n$doc = ManifestDocument::fromString(file_get_contents($path));\n// after\n$content = file_get_contents($path);\nif ($content === false || trim($content) === '') {\n    throw new RuntimeException(\"Manifest file $path unreadable or empty\");\n}\n$doc = ManifestDocument::fromString($content);","handlingStrategy":"try-catch","validationCode":"if (!is_string($xml) || trim($xml) === '') { throw new InvalidArgumentException('Manifest XML string is empty'); }","typeGuard":"function isNonEmptyString($v): bool { return is_string($v) && trim($v) !== ''; }","tryCatchPattern":"try { $doc = ManifestDocument::fromString($xml); } catch (ManifestDocumentException $e) { $cause = $e->getPrevious(); log_error($cause ? $cause->getMessage() : $e->getMessage()); }","preventionTips":["Never pass raw file_get_contents output without checking for false/empty","Prefer ManifestDocument::fromFile() over manual read + fromString","Sanity-check the string starts with '<?xml' or '<phar' before parsing"],"tags":["xml","domdocument","manifest"],"backgroundTag":"xml-parse-error","analyzedSha":"c581d4941e196459bf76c945a8ca922963a66708","analyzedAt":"2026-09-14T11:08:47.165Z","contentChangedAt":"2026-09-14T11:08:47.165Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}