feat(SocketReactor): post ErrorNotification on exception #3702

This commit is contained in:
Alex Fabijanic
2022-07-20 13:47:03 +02:00
parent 652f79319c
commit 7989d961d6
5 changed files with 45 additions and 16 deletions

View File

@@ -85,14 +85,36 @@ class Net_API ErrorNotification: public SocketNotification
/// This notification is sent if a socket has signalled an error.
{
public:
ErrorNotification(SocketReactor* pReactor);
ErrorNotification(SocketReactor* pReactor, int code = 0, const std::string& description = "");
/// Creates the ErrorNotification for the given SocketReactor.
~ErrorNotification();
/// Destroys the ErrorNotification.
int code() const;
/// Returns the error code.
const std::string& description() const;
/// Returns error description.
private:
int _code = 0;
std::string _description;
};
inline int ErrorNotification::code() const
{
return _code;
}
inline const std::string& ErrorNotification::description() const
{
return _description;
}
class Net_API TimeoutNotification: public SocketNotification
/// This notification is sent if no other event has occurred
/// for a specified time.

View File

@@ -123,9 +123,10 @@ public:
virtual ~SocketReactor();
/// Destroys the SocketReactor.
void run();
virtual void run();
/// Runs the SocketReactor. The reactor will run
/// until stop() is called (in a separate thread).
/// Can be overriden by inheriting classes.
void stop();
/// Stops the SocketReactor.
@@ -186,11 +187,11 @@ protected:
/// implementations.
virtual void onBusy();
/// Called when the SocketReactor is busy and at least one notification
/// has been dispatched.
///
/// Can be overridden by subclasses to perform additional
/// periodic tasks. The default implementation does nothing.
/// Must be overridden by subclasses (alongside the run() override) to perform
/// additional periodic tasks. The default implementation does nothing.
void onError(int code, const std::string& description);
/// Notifies all subscribers when the reactor loop throws an exception.
void dispatch(const Socket& socket, SocketNotification* pNotification);
/// Dispatches the given notification to all observers

View File

@@ -58,8 +58,10 @@ WritableNotification::~WritableNotification()
}
ErrorNotification::ErrorNotification(SocketReactor* pReactor):
SocketNotification(pReactor)
ErrorNotification::ErrorNotification(SocketReactor* pReactor, int code, const std::string& description):
SocketNotification(pReactor),
_code(code),
_description(description)
{
}

View File

@@ -94,14 +94,17 @@ void SocketReactor::run()
}
catch (Exception& exc)
{
onError(exc.code(), exc.displayText());
ErrorHandler::handle(exc);
}
catch (std::exception& exc)
{
onError(0, exc.what());
ErrorHandler::handle(exc);
}
catch (...)
{
onError(0, "unknown exception");
ErrorHandler::handle();
}
}
@@ -244,6 +247,12 @@ void SocketReactor::onBusy()
}
void SocketReactor::onError(int code, const std::string& description)
{
dispatch(new ErrorNotification(this, code, description));
}
void SocketReactor::dispatch(const Socket& socket, SocketNotification* pNotification)
{
NotifierPtr pNotifier = getNotifier(socket);

View File

@@ -36,6 +36,7 @@ using Poco::Net::SocketNotification;
using Poco::Net::ReadableNotification;
using Poco::Net::WritableNotification;
using Poco::Net::TimeoutNotification;
using Poco::Net::ErrorNotification;
using Poco::Net::ShutdownNotification;
using Poco::Observer;
using Poco::IllegalStateException;
@@ -294,12 +295,6 @@ namespace
reactor()->stop();
}
void onError(int error)
{
_failed = true;
reactor()->stop();
}
bool failed() const
{
return _failed;
@@ -479,7 +474,7 @@ void SocketReactorTest::testSocketConnectorFail()
assertTrue (!connector.failed());
assertTrue (!connector.shutdown());
reactor.run();
//assertTrue (connector.failed());
assertTrue (connector.failed());
assertTrue (connector.shutdown());
}