From 2a0108af84824c4c2a77f0163ae99f4ae43fda0a Mon Sep 17 00:00:00 2001 From: Timm Friebe Date: Sun, 21 Jun 2026 19:15:54 +0200 Subject: [PATCH] Refactor I/O exceptions --- src/main/php/web/io/Incomplete.class.php | 8 ++++---- src/main/php/web/io/ReadChunks.class.php | 8 ++++---- src/main/php/web/io/ReadLength.class.php | 4 ++-- src/main/php/web/io/Stream.class.php | 2 +- src/main/php/xp/web/Upload.class.php | 2 +- src/main/php/xp/web/srv/CannotWrite.class.php | 4 ++-- src/main/php/xp/web/srv/Workers.class.php | 8 ++++---- src/test/php/web/unittest/io/IncompleteTest.class.php | 8 ++++---- src/test/php/web/unittest/io/PartsTest.class.php | 4 ++-- src/test/php/web/unittest/io/ReadChunksTest.class.php | 8 ++++---- src/test/php/web/unittest/io/ReadLengthTest.class.php | 4 ++-- src/test/php/web/unittest/io/StreamTest.class.php | 6 +++--- .../php/web/unittest/server/ForwardRequestsTest.class.php | 6 +++--- src/test/php/web/unittest/server/SAPITest.class.php | 6 +++--- src/test/php/web/unittest/server/UploadTest.class.php | 6 +++--- 15 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/main/php/web/io/Incomplete.class.php b/src/main/php/web/io/Incomplete.class.php index d8b94d93..2271aecf 100755 --- a/src/main/php/web/io/Incomplete.class.php +++ b/src/main/php/web/io/Incomplete.class.php @@ -1,6 +1,6 @@ error; } - /** @return io.IOException */ + /** @return io.OperationFailed */ private function notSupported() { - return new OperationNotSupportedException('Cannot read from incomplete part (error= '.$this->error.')'); + return new NotSupported('Cannot read from incomplete part (error= '.$this->error.')'); } /** @return string */ @@ -56,7 +56,7 @@ public function bytes() { throw $this->notSupported(); } * @param io.Path|io.Folder|io.streams.OutputStream|string $target * @return iterable * @throws lang.IllegalArgumentException if filename is invalid - * @throws io.IOException + * @throws io.OperationFailed */ public function transmit($target) { throw $this->notSupported(); yield; } diff --git a/src/main/php/web/io/ReadChunks.class.php b/src/main/php/web/io/ReadChunks.class.php index 6212c8fe..e7c0d0d2 100755 --- a/src/main/php/web/io/ReadChunks.class.php +++ b/src/main/php/web/io/ReadChunks.class.php @@ -1,6 +1,6 @@ input->readLine() ?? ''; if (1 !== sscanf($size, '%x', $l)) { - throw new IOException('No chunk segment present (`'.addcslashes($size, "\0..\37").'`)'); + throw new OperationFailed('No chunk segment present (`'.addcslashes($size, "\0..\37").'`)'); } // Chunk with 0 length indicates EOF @@ -81,7 +81,7 @@ public function read($limit= 8192) { $chunk= substr($this->buffer, 0, min($limit, $remaining)); if ('' === $chunk) { $this->remaining= 0; - throw new IOException('Unexpected EOF'); + throw new OperationFailed('Unexpected EOF'); } $length= strlen($chunk); diff --git a/src/main/php/web/io/ReadLength.class.php b/src/main/php/web/io/ReadLength.class.php index 3fe14f6c..ccafcb1b 100755 --- a/src/main/php/web/io/ReadLength.class.php +++ b/src/main/php/web/io/ReadLength.class.php @@ -1,6 +1,6 @@ input->read(min($limit, $this->remaininig)); if ('' === $chunk) { $this->remaininig= 0; - throw new IOException('EOF'); + throw new OperationFailed('EOF'); } $this->remaininig-= strlen($chunk); diff --git a/src/main/php/web/io/Stream.class.php b/src/main/php/web/io/Stream.class.php index a3c6d55d..fd074415 100755 --- a/src/main/php/web/io/Stream.class.php +++ b/src/main/php/web/io/Stream.class.php @@ -75,7 +75,7 @@ public function bytes() { * @param io.Path|io.Folder|io.streams.OutputStream|string $target * @return iterable * @throws lang.IllegalArgumentException if filename is invalid - * @throws io.IOException + * @throws io.OperationFailed */ public function transmit($target) { if ($target instanceof OutputStream) { diff --git a/src/main/php/xp/web/Upload.class.php b/src/main/php/xp/web/Upload.class.php index 048a394d..6d67f2b2 100755 --- a/src/main/php/xp/web/Upload.class.php +++ b/src/main/php/xp/web/Upload.class.php @@ -65,7 +65,7 @@ public function bytes() { * @param io.Path|io.Folder|io.streams.OutputStream|string $target * @return iterable * @throws lang.IllegalArgumentException if filename is invalid - * @throws io.IOException + * @throws io.OperationFailed */ public function transmit($target) { diff --git a/src/main/php/xp/web/srv/CannotWrite.class.php b/src/main/php/xp/web/srv/CannotWrite.class.php index aa52dc97..19ed1e64 100755 --- a/src/main/php/xp/web/srv/CannotWrite.class.php +++ b/src/main/php/xp/web/srv/CannotWrite.class.php @@ -1,8 +1,8 @@ message; } diff --git a/src/main/php/xp/web/srv/Workers.class.php b/src/main/php/xp/web/srv/Workers.class.php index 5c7020a6..76f87159 100755 --- a/src/main/php/xp/web/srv/Workers.class.php +++ b/src/main/php/xp/web/srv/Workers.class.php @@ -1,6 +1,6 @@ name()) $commandLine= 'exec '.$commandLine; if (!($proc= proc_open($commandLine, [STDIN, STDOUT, ['pipe', 'w']], $pipes, null, null, ['bypass_shell' => true]))) { - throw new IOException('Cannot execute `'.$commandLine.'`'); + throw new OperationFailed('Cannot execute `'.$commandLine.'`'); } // Parse `[...] PHP 8.3.15 Development Server (http://127.0.0.1:60922) started` @@ -78,7 +78,7 @@ public function launch() { if (!preg_match('/\([a-z]+:\/\/([0-9.]+):([0-9]+)\)/', $line, $matches)) { proc_terminate($proc, 2); proc_close($proc); - throw new IOException('Cannot determine bound port: `'.implode('', $lines).'`'); + throw new OperationFailed('Cannot determine bound port: `'.implode('', $lines).'`'); } return new Worker($proc, new Socket($matches[1], (int)$matches[2])); diff --git a/src/test/php/web/unittest/io/IncompleteTest.class.php b/src/test/php/web/unittest/io/IncompleteTest.class.php index 96549b65..3d000e8a 100755 --- a/src/test/php/web/unittest/io/IncompleteTest.class.php +++ b/src/test/php/web/unittest/io/IncompleteTest.class.php @@ -1,6 +1,6 @@ bytes(); } - #[Test, Expect(OperationNotSupportedException::class)] + #[Test, Expect(NotSupported::class)] public function cannot_transmit() { $it= (new Incomplete('upload', UPLOAD_ERR_INI_SIZE))->transmit('./uploads'); while ($it->valid()) { @@ -42,7 +42,7 @@ public function cannot_transmit() { } } - #[Test, Expect(OperationNotSupportedException::class)] + #[Test, Expect(NotSupported::class)] public function cannot_read_bytes() { (new Incomplete('upload', UPLOAD_ERR_INI_SIZE))->read(); } diff --git a/src/test/php/web/unittest/io/PartsTest.class.php b/src/test/php/web/unittest/io/PartsTest.class.php index 4cded842..c08141ba 100755 --- a/src/test/php/web/unittest/io/PartsTest.class.php +++ b/src/test/php/web/unittest/io/PartsTest.class.php @@ -1,6 +1,6 @@ parts( '--%1$s', diff --git a/src/test/php/web/unittest/io/ReadChunksTest.class.php b/src/test/php/web/unittest/io/ReadChunksTest.class.php index 0e86a631..88dea1d7 100755 --- a/src/test/php/web/unittest/io/ReadChunksTest.class.php +++ b/src/test/php/web/unittest/io/ReadChunksTest.class.php @@ -1,6 +1,6 @@ input("0\r\n\r\n")); } - #[Test, Expect(IOException::class)] + #[Test, Expect(OperationFailed::class)] public function raises_exception_from_read_when_non_chunked_data_appears() { $fixture= new ReadChunks($this->input('')); $fixture->read(); } - #[Test, Expect(IOException::class)] + #[Test, Expect(OperationFailed::class)] public function raises_exception_from_available_when_non_chunked_data_appears() { $fixture= new ReadChunks($this->input('')); $fixture->available(); @@ -130,7 +130,7 @@ public function raises_exception_on_eof_in_the_middle_of_data() { $fixture= new ReadChunks($this->input("ff\r\n...💣")); $fixture->read(); - Assert::throws(IOException::class, fn() => $fixture->read(1)); + Assert::throws(OperationFailed::class, fn() => $fixture->read(1)); } #[Test, Values([4, 8192])] diff --git a/src/test/php/web/unittest/io/ReadLengthTest.class.php b/src/test/php/web/unittest/io/ReadLengthTest.class.php index c1aaa60a..ae3ae69f 100755 --- a/src/test/php/web/unittest/io/ReadLengthTest.class.php +++ b/src/test/php/web/unittest/io/ReadLengthTest.class.php @@ -1,6 +1,6 @@ input('Test'), 10); $fixture->read(); - Assert::throws(IOException::class, fn() => $fixture->read(1)); + Assert::throws(OperationFailed::class, fn() => $fixture->read(1)); } #[Test, Values([4, 8192])] diff --git a/src/test/php/web/unittest/io/StreamTest.class.php b/src/test/php/web/unittest/io/StreamTest.class.php index bd6654b4..7a14b604 100755 --- a/src/test/php/web/unittest/io/StreamTest.class.php +++ b/src/test/php/web/unittest/io/StreamTest.class.php @@ -1,7 +1,7 @@ bytes()); } - #[Test, Expect(IOException::class)] + #[Test, Expect(OperationFailed::class)] public function exceptions_raised_while_storing() { $out= new class() extends MemoryOutputStream { - public function write($bytes) { throw new IOException('Disk full'); } + public function write($bytes) { throw new OperationFailed('Disk full'); } }; $it= $this->newFixture(self::NAME, 'Test')->transmit($out); while ($it->valid()) { diff --git a/src/test/php/web/unittest/server/ForwardRequestsTest.class.php b/src/test/php/web/unittest/server/ForwardRequestsTest.class.php index a2d8c00e..046e4610 100755 --- a/src/test/php/web/unittest/server/ForwardRequestsTest.class.php +++ b/src/test/php/web/unittest/server/ForwardRequestsTest.class.php @@ -1,6 +1,6 @@ forward($client, $backend); - } catch (IOException $expected) { + } catch (OperationFailed $expected) { // ... } diff --git a/src/test/php/web/unittest/server/SAPITest.class.php b/src/test/php/web/unittest/server/SAPITest.class.php index 3558f369..0edb50fe 100755 --- a/src/test/php/web/unittest/server/SAPITest.class.php +++ b/src/test/php/web/unittest/server/SAPITest.class.php @@ -1,6 +1,6 @@ toString(); }, )); } - #[Test, Expect(OperationNotSupportedException::class)] + #[Test, Expect(NotSupported::class)] public function read_from_incomplete_upload() { $parts= $this->parts($this->incomplete('test.txt', UPLOAD_ERR_PARTIAL)); $parts['file']->bytes(); } - #[Test, Expect(OperationNotSupportedException::class)] + #[Test, Expect(NotSupported::class)] public function stream_incomplete_upload() { $parts= $this->parts($this->incomplete('test.txt', UPLOAD_ERR_PARTIAL)); Streams::readAll($parts['file']); diff --git a/src/test/php/web/unittest/server/UploadTest.class.php b/src/test/php/web/unittest/server/UploadTest.class.php index 6e37e744..4e64a6dc 100755 --- a/src/test/php/web/unittest/server/UploadTest.class.php +++ b/src/test/php/web/unittest/server/UploadTest.class.php @@ -1,7 +1,7 @@ bytes()); } - #[Test, Expect(IOException::class)] + #[Test, Expect(OperationFailed::class)] public function exceptions_raised_while_storing() { $in= new MemoryInputStream('Test'); $out= new class() extends MemoryOutputStream { - public function write($bytes) { throw new IOException('Disk full'); } + public function write($bytes) { throw new OperationFailed('Disk full'); } }; $it= $this->newFixture(self::NAME, Streams::readableUri($in))->transmit($out);