[network] Error handling reform

`network.cpp` has several error paths which either:
- report "Unhandled host socket error=n" and return `SUCCESS`, or
- switch on a few possible errors, log them, and translate them to
  Errno; the same switch statement is copied and pasted in multiple
  places in the code

Convert these paths to use a helper function `GetAndLogLastError`, which
is roughly the equivalent of one of the switch statements, but:
- handling more cases (both ones that were already in `Errno`, and a few
  more I added), and
- using OS functions to convert the error to a string when logging, so
  it'll describe the error even if it's not one of the ones in the
  switch statement.
  - To handle this, refactor the logic in `GetLastErrorMsg` to expose a
    new function `NativeErrorToString` which takes the error number
    explicitly as an argument.  And improve the Windows version a bit.

Also, add a test which exercises two random error paths.
This commit is contained in:
comex 2021-01-24 15:17:02 -05:00
parent 9e9341f4b4
commit 2910aa77b2
6 changed files with 147 additions and 111 deletions

View file

@ -5,6 +5,7 @@ add_executable(tests
common/param_package.cpp
common/ring_buffer.cpp
core/core_timing.cpp
core/network/network.cpp
tests.cpp
video_core/buffer_base.cpp
)

View file

@ -0,0 +1,28 @@
// Copyright 2021 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <catch2/catch.hpp>
#include "core/network/network.h"
#include "core/network/sockets.h"
TEST_CASE("Network::Errors", "[core]") {
Network::NetworkInstance network_instance; // initialize network
Network::Socket socks[2];
for (Network::Socket& sock : socks) {
REQUIRE(sock.Initialize(Network::Domain::INET, Network::Type::STREAM,
Network::Protocol::TCP) == Network::Errno::SUCCESS);
}
Network::SockAddrIn addr{
Network::Domain::INET,
{127, 0, 0, 1},
1, // hopefully nobody running this test has something listening on port 1
};
REQUIRE(socks[0].Connect(addr) == Network::Errno::CONNREFUSED);
std::vector<u8> message{1, 2, 3, 4};
REQUIRE(socks[1].Recv(0, message).second == Network::Errno::NOTCONN);
}