Consistently print errors in factory functions

This commit is contained in:
vittorioromeo 2024-06-10 17:11:43 +02:00 committed by Vittorio Romeo
parent 52fb26c6cd
commit a303cee386
9 changed files with 106 additions and 28 deletions

View File

@ -235,7 +235,8 @@ private:
/// \brief Try opening the music file from an optional input sound file
///
////////////////////////////////////////////////////////////
[[nodiscard]] static std::optional<Music> tryOpenFromFile(std::optional<InputSoundFile>&& optFile);
[[nodiscard]] static std::optional<Music> tryOpenFromInputSoundFile(std::optional<InputSoundFile>&& optFile,
const char* errorContext);
////////////////////////////////////////////////////////////
/// \brief Initialize the internal state after loading a new music

View File

@ -56,6 +56,8 @@ public:
///
/// \param address IP address or network name
///
/// \return Address if provided argument was valid, otherwise `std::nullopt`
///
////////////////////////////////////////////////////////////
[[nodiscard]] static std::optional<IpAddress> resolve(std::string_view address);
@ -128,7 +130,7 @@ public:
/// Unlike getPublicAddress, this function is fast and may be
/// used safely anywhere.
///
/// \return Local IP address of the computer
/// \return Local IP address of the computer on success, `std::nullopt` otherwise
///
/// \see getPublicAddress
///
@ -152,7 +154,7 @@ public:
///
/// \param timeout Maximum time to wait
///
/// \return Public IP address of the computer
/// \return Public IP address of the computer on success, `std::nullopt` otherwise
///
/// \see getLocalAddress
///

View File

@ -34,6 +34,7 @@
#include <SFML/System/InputStream.hpp>
#include <SFML/System/MemoryInputStream.hpp>
#include <SFML/System/Time.hpp>
#include <SFML/System/Utils.hpp>
#include <ostream>
#include <utility>
@ -71,19 +72,32 @@ std::optional<InputSoundFile> InputSoundFile::openFromFile(const std::filesystem
// Find a suitable reader for the file type
auto reader = SoundFileFactory::createReaderFromFilename(filename);
if (!reader)
{
// Error message generated in called function.
return std::nullopt;
}
// Wrap the file into a stream
auto file = std::make_unique<FileInputStream>();
// Open it
if (!file->open(filename))
{
err() << "Failed to open input sound file from file (couldn't open file input stream)\n"
<< formatDebugPathInfo(filename) << std::endl;
return std::nullopt;
}
// Pass the stream to the reader
auto info = reader->open(*file);
if (!info)
{
err() << "Failed to open input sound file from file (reader open failure)\n"
<< formatDebugPathInfo(filename) << std::endl;
return std::nullopt;
}
return InputSoundFile(std::move(reader), std::move(file), info->sampleCount, info->sampleRate, std::move(info->channelMap));
}
@ -95,7 +109,10 @@ std::optional<InputSoundFile> InputSoundFile::openFromMemory(const void* data, s
// Find a suitable reader for the file type
auto reader = SoundFileFactory::createReaderFromMemory(data, sizeInBytes);
if (!reader)
{
// Error message generated in called function.
return std::nullopt;
}
// Wrap the memory file into a stream
auto memory = std::make_unique<MemoryInputStream>(data, sizeInBytes);
@ -103,7 +120,10 @@ std::optional<InputSoundFile> InputSoundFile::openFromMemory(const void* data, s
// Pass the stream to the reader
auto info = reader->open(*memory);
if (!info)
{
err() << "Failed to open input sound file from memory (reader open failure)" << std::endl;
return std::nullopt;
}
return InputSoundFile(std::move(reader), std::move(memory), info->sampleCount, info->sampleRate, std::move(info->channelMap));
}
@ -115,7 +135,10 @@ std::optional<InputSoundFile> InputSoundFile::openFromStream(InputStream& stream
// Find a suitable reader for the file type
auto reader = SoundFileFactory::createReaderFromStream(stream);
if (!reader)
{
// Error message generated in called function.
return std::nullopt;
}
// Don't forget to reset the stream to its beginning before re-opening it
if (stream.seek(0) != 0)
@ -127,7 +150,10 @@ std::optional<InputSoundFile> InputSoundFile::openFromStream(InputStream& stream
// Pass the stream to the reader
auto info = reader->open(stream);
if (!info)
{
err() << "Failed to open input sound file from stream (reader open failure)" << std::endl;
return std::nullopt;
}
return InputSoundFile(std::move(reader), {&stream, false}, info->sampleCount, info->sampleRate, std::move(info->channelMap));
}

View File

@ -79,10 +79,13 @@ Music& Music::operator=(Music&&) noexcept = default;
////////////////////////////////////////////////////////////
std::optional<Music> Music::tryOpenFromFile(std::optional<InputSoundFile>&& optFile)
std::optional<Music> Music::tryOpenFromInputSoundFile(std::optional<InputSoundFile>&& optFile, const char* errorContext)
{
if (!optFile.has_value())
{
err() << "Failed to open music from " << errorContext << std::endl;
return std::nullopt;
}
// TODO: apply RVO here via passkey idiom
return Music(std::move(*optFile));
@ -92,21 +95,21 @@ std::optional<Music> Music::tryOpenFromFile(std::optional<InputSoundFile>&& optF
////////////////////////////////////////////////////////////
std::optional<Music> Music::openFromFile(const std::filesystem::path& filename)
{
return tryOpenFromFile(InputSoundFile::openFromFile(filename));
return tryOpenFromInputSoundFile(InputSoundFile::openFromFile(filename), "file");
}
////////////////////////////////////////////////////////////
std::optional<Music> Music::openFromMemory(const void* data, std::size_t sizeInBytes)
{
return tryOpenFromFile(InputSoundFile::openFromMemory(data, sizeInBytes));
return tryOpenFromInputSoundFile(InputSoundFile::openFromMemory(data, sizeInBytes), "memory");
}
////////////////////////////////////////////////////////////
std::optional<Music> Music::openFromStream(InputStream& stream)
{
return tryOpenFromFile(InputSoundFile::openFromStream(stream));
return tryOpenFromInputSoundFile(InputSoundFile::openFromStream(stream), "stream");
}

View File

@ -29,6 +29,8 @@
#include <SFML/Audio/SoundFileFactory.hpp>
#include <SFML/Audio/SoundFileWriter.hpp>
#include <SFML/System/Err.hpp>
#include <cassert>
@ -44,11 +46,15 @@ std::optional<OutputSoundFile> OutputSoundFile::openFromFile(
// Find a suitable writer for the file type
auto writer = SoundFileFactory::createWriterFromFilename(filename);
if (!writer)
{
// Error message generated in called function.
return std::nullopt;
}
// Pass the stream to the reader
if (!writer->open(filename, sampleRate, channelCount, channelMap))
{
err() << "Failed to open output sound file from file (writer open failure)" << std::endl;
return std::nullopt;
}

View File

@ -72,7 +72,8 @@ std::optional<SoundBuffer> SoundBuffer::loadFromFile(const std::filesystem::path
{
if (auto file = InputSoundFile::openFromFile(filename))
return initialize(*file);
else
err() << "Failed to open sound buffer from file" << std::endl;
return std::nullopt;
}
@ -82,7 +83,8 @@ std::optional<SoundBuffer> SoundBuffer::loadFromMemory(const void* data, std::si
{
if (auto file = InputSoundFile::openFromMemory(data, sizeInBytes))
return initialize(*file);
else
err() << "Failed to open sound buffer from memory" << std::endl;
return std::nullopt;
}
@ -92,7 +94,8 @@ std::optional<SoundBuffer> SoundBuffer::loadFromStream(InputStream& stream)
{
if (auto file = InputSoundFile::openFromStream(stream))
return initialize(*file);
else
err() << "Failed to open sound buffer from stream" << std::endl;
return std::nullopt;
}
@ -223,7 +226,11 @@ std::optional<SoundBuffer> SoundBuffer::initialize(InputSoundFile& file)
// Update the internal buffer with the new samples
SoundBuffer soundBuffer(std::move(samples));
if (!soundBuffer.update(file.getChannelCount(), file.getSampleRate(), file.getChannelMap()))
{
err() << "Failed to initialize sound buffer (internal update failure)" << std::endl;
return std::nullopt;
}
return soundBuffer;
}
else

View File

@ -266,30 +266,33 @@ std::optional<Texture> Texture::create(const Vector2u& size, bool sRgb)
////////////////////////////////////////////////////////////
std::optional<Texture> Texture::loadFromFile(const std::filesystem::path& filename, bool sRgb, const IntRect& area)
{
const auto image = sf::Image::loadFromFile(filename);
if (!image)
return std::nullopt;
if (const auto image = sf::Image::loadFromFile(filename))
return loadFromImage(*image, sRgb, area);
err() << "Failed to load texture from file" << std::endl;
return std::nullopt;
}
////////////////////////////////////////////////////////////
std::optional<Texture> Texture::loadFromMemory(const void* data, std::size_t size, bool sRgb, const IntRect& area)
{
const auto image = sf::Image::loadFromMemory(data, size);
if (!image)
return std::nullopt;
if (const auto image = sf::Image::loadFromMemory(data, size))
return loadFromImage(*image, sRgb, area);
err() << "Failed to load texture from memory" << std::endl;
return std::nullopt;
}
////////////////////////////////////////////////////////////
std::optional<Texture> Texture::loadFromStream(InputStream& stream, bool sRgb, const IntRect& area)
{
const auto image = sf::Image::loadFromStream(stream);
if (!image)
return std::nullopt;
if (const auto image = sf::Image::loadFromStream(stream))
return loadFromImage(*image, sRgb, area);
err() << "Failed to load texture from stream" << std::endl;
return std::nullopt;
}
@ -307,11 +310,11 @@ std::optional<Texture> Texture::loadFromImage(const Image& image, bool sRgb, con
if (auto texture = sf::Texture::create(image.getSize(), sRgb))
{
texture->update(image);
return texture;
}
else
{
// Error message generated in called function.
return std::nullopt;
}
}
@ -354,6 +357,7 @@ std::optional<Texture> Texture::loadFromImage(const Image& image, bool sRgb, con
}
else
{
// Error message generated in called function.
return std::nullopt;
}
}

View File

@ -29,6 +29,8 @@
#include <SFML/Network/IpAddress.hpp>
#include <SFML/Network/SocketImpl.hpp>
#include <SFML/System/Err.hpp>
#include <istream>
#include <ostream>
@ -49,7 +51,10 @@ std::optional<IpAddress> IpAddress::resolve(std::string_view address)
using namespace std::string_view_literals;
if (address.empty())
{
// Not generating en error message here as resolution failure is a valid outcome.
return std::nullopt;
}
if (address == "255.255.255.255"sv)
{
@ -81,6 +86,7 @@ std::optional<IpAddress> IpAddress::resolve(std::string_view address)
return IpAddress(ntohl(ip));
}
// Not generating en error message here as resolution failure is a valid outcome.
return std::nullopt;
}
@ -125,13 +131,18 @@ std::optional<IpAddress> IpAddress::getLocalAddress()
// Create the socket
const SocketHandle sock = socket(PF_INET, SOCK_DGRAM, 0);
if (sock == priv::SocketImpl::invalidSocket())
{
err() << "Failed to retrieve local address (invalid socket)" << std::endl;
return std::nullopt;
}
// Connect the socket to localhost on any port
sockaddr_in address = priv::SocketImpl::createAddress(ntohl(INADDR_LOOPBACK), 9);
if (connect(sock, reinterpret_cast<sockaddr*>(&address), sizeof(address)) == -1)
{
priv::SocketImpl::close(sock);
err() << "Failed to retrieve local address (socket connection failure)" << std::endl;
return std::nullopt;
}
@ -140,6 +151,8 @@ std::optional<IpAddress> IpAddress::getLocalAddress()
if (getsockname(sock, reinterpret_cast<sockaddr*>(&address), &size) == -1)
{
priv::SocketImpl::close(sock);
err() << "Failed to retrieve local address (socket local address retrieval failure)" << std::endl;
return std::nullopt;
}
@ -163,10 +176,15 @@ std::optional<IpAddress> IpAddress::getPublicAddress(Time timeout)
Http server("www.sfml-dev.org");
const Http::Request request("/ip-provider.php", Http::Request::Method::Get);
const Http::Response page = server.sendRequest(request, timeout);
if (page.getStatus() == Http::Response::Status::Ok)
const Http::Response::Status status = page.getStatus();
if (status == Http::Response::Status::Ok)
return IpAddress::resolve(page.getBody());
// Something failed: return an invalid address
err() << "Failed to retrieve public address from external IP resolution server (HTTP response status "
<< static_cast<int>(status) << ")" << std::endl;
return std::nullopt;
}

View File

@ -28,9 +28,11 @@
#include <SFML/Window/Cursor.hpp>
#include <SFML/Window/CursorImpl.hpp>
#include <SFML/System/Err.hpp>
#include <SFML/System/Vector2.hpp>
#include <memory>
#include <ostream>
namespace sf
{
@ -57,11 +59,17 @@ Cursor& Cursor::operator=(Cursor&&) noexcept = default;
std::optional<Cursor> Cursor::loadFromPixels(const std::uint8_t* pixels, Vector2u size, Vector2u hotspot)
{
if ((pixels == nullptr) || (size.x == 0) || (size.y == 0))
{
err() << "Failed to load cursor from pixels (invalid arguments)" << std::endl;
return std::nullopt;
}
Cursor cursor;
if (!cursor.m_impl->loadFromPixels(pixels, size, hotspot))
{
// Error message generated in called function.
return std::nullopt;
}
return cursor;
}
@ -72,7 +80,10 @@ std::optional<Cursor> Cursor::loadFromSystem(Type type)
{
Cursor cursor;
if (!cursor.m_impl->loadFromSystem(type))
{
// Error message generated in called function.
return std::nullopt;
}
return cursor;
}