Skip to content

Commit

Permalink
Merge pull request #178 from clue-labs/unhandled-rejections
Browse files Browse the repository at this point in the history
Update close handler to avoid unhandled promise rejections
  • Loading branch information
WyriHaximus authored Jul 10, 2023
2 parents a13dbbb + 9c342f3 commit f9c55f5
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 22 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"evenement/evenement": "^3.0 || ^2.1 || ^1.1",
"react/event-loop": "^1.2",
"react/promise": "^3 || ^2.7",
"react/promise-stream": "^1.4",
"react/promise-stream": "^1.6",
"react/promise-timer": "^1.9",
"react/socket": "^1.12"
},
Expand Down
2 changes: 2 additions & 0 deletions src/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ public function createConnection(
// either close successful connection or cancel pending connection attempt
$connecting->then(function (SocketConnectionInterface $connection) {
$connection->close();
}, function () {
// ignore to avoid reporting unhandled rejection
});
$connecting->cancel();
});
Expand Down
2 changes: 2 additions & 0 deletions src/Io/LazyConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ public function close()
if ($this->connecting !== null) {
$this->connecting->then(function (ConnectionInterface $connection) {
$connection->close();
}, function () {
// ignore to avoid reporting unhandled rejection
});
if ($this->connecting !== null) {
$this->connecting->cancel();
Expand Down
27 changes: 15 additions & 12 deletions tests/FactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ public function testConnectWithValidAuthWillRunUntilQuit()
$connection->quit()->then(function () {
echo 'closed.';
});
}, 'printf')->then(null, 'printf');
});

Loop::run();
}
Expand All @@ -296,7 +296,7 @@ public function testConnectWithValidAuthAndWithoutDbNameWillRunUntilQuit()
$connection->quit()->then(function () {
echo 'closed.';
});
}, 'printf')->then(null, 'printf');
});

Loop::run();
}
Expand All @@ -313,7 +313,7 @@ public function testConnectWithValidAuthWillIgnoreNegativeTimeoutAndRunUntilQuit
$connection->quit()->then(function () {
echo 'closed.';
});
}, 'printf')->then(null, 'printf');
});

Loop::run();
}
Expand All @@ -333,8 +333,7 @@ public function testConnectWithValidAuthCanPingAndThenQuit()
echo 'closed.';
});
});

}, 'printf')->then(null, 'printf');
});

Loop::run();
}
Expand All @@ -354,14 +353,14 @@ public function testConnectWithValidAuthCanQueuePingAndQuit()
$connection->quit()->then(function () {
echo 'closed.';
});
}, 'printf')->then(null, 'printf');
});

Loop::run();
}

public function testConnectWithValidAuthQuitOnlyOnce()
{
$this->expectOutputString('connected.closed.');
$this->expectOutputString('connected.rejected.closed.');

$factory = new Factory();

Expand All @@ -372,9 +371,11 @@ public function testConnectWithValidAuthQuitOnlyOnce()
echo 'closed.';
});
$connection->quit()->then(function () {
echo 'closed.';
echo 'never reached.';
}, function () {
echo 'rejected.';
});
}, 'printf')->then(null, 'printf');
});

Loop::run();
}
Expand All @@ -397,7 +398,7 @@ public function testConnectWithValidAuthCanCloseOnlyOnce()

$connection->close();
$connection->close();
}, 'printf')->then(null, 'printf');
});

Loop::run();
}
Expand Down Expand Up @@ -425,7 +426,7 @@ public function testConnectWithValidAuthCanCloseAndAbortPing()
echo 'aborted queued (' . $e->getMessage() . ').';
});
$connection->close();
}, 'printf')->then(null, 'printf');
});

Loop::run();
}
Expand Down Expand Up @@ -626,7 +627,7 @@ public function testConnectLazyWithInvalidAuthWillRejectPingButWillNotEmitErrorO

public function testConnectLazyWithValidAuthWillPingBeforeQuitButNotAfter()
{
$this->expectOutputString('ping.closed.');
$this->expectOutputString('rejected.ping.closed.');

$factory = new Factory();

Expand All @@ -643,6 +644,8 @@ public function testConnectLazyWithValidAuthWillPingBeforeQuitButNotAfter()

$connection->ping()->then(function () {
echo 'never reached';
}, function () {
echo 'rejected.';
});

Loop::run();
Expand Down
10 changes: 8 additions & 2 deletions tests/Io/LazyConnectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@ public function testPingWillNotCloseConnectionWhenPendingConnectionFails()
$connection->on('error', $this->expectCallableNever());
$connection->on('close', $this->expectCallableNever());

$connection->ping();
$promise = $connection->ping();

$promise->then(null, $this->expectCallableOnce()); // avoid reporting unhandled rejection

$deferred->reject(new \RuntimeException());
}

public function testPingWillNotCloseConnectionWhenUnderlyingConnectionCloses()
{
$base = $this->getMockBuilder('React\MySQL\Io\LazyConnection')->setMethods(['ping'])->disableOriginalConstructor()->getMock();
Expand Down Expand Up @@ -678,7 +681,10 @@ public function testCloseAfterPingDoesNotEmitConnectionErrorFromAbortedConnectio
$connection->on('error', $this->expectCallableNever());
$connection->on('close', $this->expectCallableOnce());

$connection->ping();
$promise = $connection->ping();

$promise->then(null, $this->expectCallableOnce()); // avoid reporting unhandled rejection

$connection->close();
}

Expand Down
18 changes: 11 additions & 7 deletions tests/ResultQueryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ public function testSelectStaticText()
$this->assertCount(1, $command->resultRows);
$this->assertCount(1, $command->resultRows[0]);
$this->assertSame('foo', reset($command->resultRows[0]));

$this->assertInstanceOf('React\MySQL\Connection', $conn);
});

$connection->quit();
Expand Down Expand Up @@ -57,7 +55,7 @@ public function testSelectStaticValueWillBeReturnedAsIs($value)
$this->assertCount(1, $command->resultRows);
$this->assertCount(1, $command->resultRows[0]);
$this->assertSame($expected, reset($command->resultRows[0]));
})->then(null, 'printf');
});

$connection->quit();
Loop::run();
Expand All @@ -82,7 +80,7 @@ public function testSelectStaticValueWillBeReturnedAsIsWithNoBackslashEscapesSql
$this->assertCount(1, $command->resultRows);
$this->assertCount(1, $command->resultRows[0]);
$this->assertSame($expected, reset($command->resultRows[0]));
})->then(null, 'printf');
});

$connection->quit();
Loop::run();
Expand Down Expand Up @@ -138,7 +136,7 @@ public function testSelectLongStaticTextHasTypeStringWithValidLength()

$connection->query('SELECT ?', [$value])->then(function (QueryResult $command) use ($length) {
$this->assertCount(1, $command->resultFields);
$this->assertEquals($length * 3, $command->resultFields[0]['length']);
$this->assertEquals($length * 4, $command->resultFields[0]['length']);
$this->assertSame(Constants::FIELD_TYPE_VAR_STRING, $command->resultFields[0]['type']);
});

Expand Down Expand Up @@ -430,7 +428,7 @@ public function testInvalidSelectShouldFail()

$connection->query('select * from invalid_table')->then(
$this->expectCallableNever(),
function (\Exception $error) {
function (\Exception $error) use ($db) {
$this->assertEquals("Table '$db.invalid_table' doesn't exist", $error->getMessage());
}
);
Expand All @@ -446,7 +444,13 @@ public function testInvalidMultiStatementsShouldFailToPreventSqlInjections()
$connection->query('select 1;select 2;')->then(
$this->expectCallableNever(),
function (\Exception $error) {
$this->assertContains("You have an error in your SQL syntax", $error->getMessage());
if (method_exists($this, 'assertStringContainsString')) {
// PHPUnit 9+
$this->assertStringContainsString("You have an error in your SQL syntax", $error->getMessage());
} else {
// legacy PHPUnit < 9
$this->assertContains("You have an error in your SQL syntax", $error->getMessage());
}
}
);

Expand Down

0 comments on commit f9c55f5

Please sign in to comment.