networking-ts-impl icon indicating copy to clipboard operation
networking-ts-impl copied to clipboard

Please consider making cross platform exceptions easy to catch

Open sldr opened this issue 7 years ago • 1 comments

In the following code, reading the content requires catching std::system_error then checking for std::net::error::eof in the code() call. It would be nice if most (if not all) errors could be caught, but at least the most common cross platform errors. Note that switch (e.code()) will not work and switch (e.code().value()) doesn't work because the category will need to be checked too.

#include <string>
#include <iostream>
#include <experimental/net>
#include <experimental/buffer>
#include <experimental/internet>

namespace std {
	namespace net = std::experimental::net; // Put std::experimental::net into std::net namespace (I assume this is where it will go when approved)
}
using namespace std::string_literals; // Give me "SLDR"s -> std::string

int main()
{
	std::net::io_context myiocontext;
	std::net::ip::tcp::resolver myresolver = std::net::ip::tcp::resolver(myiocontext);
	std::net::ip::tcp::socket mysocket = std::net::ip::tcp::socket(myiocontext);
	std::net::connect(mysocket, myresolver.resolve("httpbin.org", "http"));
	for (auto r : {
			"GET /get?sldr=22 HTTP/1.0\r\n"s,
			"Host: httpbin.org\r\n"s,
			"Accept: */*\r\n"s,
			"User-Agent: Nonya\r\n"s,
			"Connection: close\r\n\r\n"s }) {
		std::net::write(mysocket, std::net::buffer(r));
	}
	// Handle http headers
	std::string headers;
	std::net::read(mysocket, std::net::dynamic_buffer(headers),
		[&headers](auto ec, auto n) -> std::size_t {
		if (ec || (headers.size() > 3 && headers.compare(headers.size() - 4, 4, "\r\n\r\n") == 0)) {
			return 0; // don't read anymore characters
		}
		else {
			return 1; // read 1 more character return 2; // read 2 more characters
		}
		});
	std::cout << headers;
	// Handle http content
	std::string content;
	try {
		bool repeat = false;
		int repeat_times = 3;
		do {
			try {
				while (0 < std::net::read(mysocket, std::net::dynamic_buffer(content))) {
					std::cout << content;
				}
			}
			catch (std::system_error e) {
				if (e.code() != std::net::error::try_again) {
					throw;
				}
				std::cout << content;
				repeat = true;
			}
			content.clear();
			repeat_times--;
		} while (repeat && repeat_times > 0);
	}
	catch (std::system_error e) {
		if (e.code() != std::net::error::eof && e.code() != std::net::error::connection_reset) {
			throw;
		}
		std::cout << content;
	}
	return 0;
}

Allowing something like the following would make the code simpler for catching errors for the users that prefer the exception method of dealing with the errors.

	// Handle http content
	std::string content;
	try {
		bool repeat = false;
		int repeat_times = 3;
		do {
			try {
				while (0 < std::net::read(mysocket, std::net::dynamic_buffer(content))) {
					std::cout << content;
				}
			}
			catch (std::net::error::try_again_error) {
				std::cout << content;
				repeat = true;
			}
			repeat_times--;
		} while (repeat && repeat_times > 0);
	}
	catch (std::net::error::eof_error) {
		std::cout << content;
	}
	catch (std::net::error::connection_reset_error) {
		std::cout << content;
	}
	return 0;

Note that the std::net::error::eof_error could be a nested exception with the currently thrown std::system_error exception being the internal exception. It could be noted that the std::system_error exception can always be thrown because unexpected platform specific errors could happen that don't map to any std::net::error::*_error exception. One down side is compiler venders (and/or stl coders) will have to decide what errors map to the common exceptions but the standard-ease wording could try to keep them from making to poor of a choice that would make users have to resort to writing code like the first example.

Thanks, SLDR (Stephen L. De Rudder)

sldr avatar Jan 14 '18 03:01 sldr

@sldr: Sounds more like something that should be added to the standard itself (there is a email address in it): http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4734.pdf

FlorianFranzen avatar Aug 06 '18 12:08 FlorianFranzen