GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — cpp-netlib misuses the boost::promise API · Issue #815 · cpp-netlib/cpp-netlib

cpp-netlib misuses the boost::promise API #815

New issue
Copy link
New issue
Copy link
Closed
Closed
cpp-netlib misuses the boost::promise API#815
Copy link

Description

@HighCommander4
HighCommander4
opened on Feb 11, 2018
Issue body actions

cpp-netlib calls boost::promise::set_exception() with a std::exception_ptr as argument in a number of places (for example, in http_async_connection::handle_received_data().

boost::promise::set_exception() has two overloads:

  void set_exception(boost::exception_ptr e);

  template <typename E>
  void set_exception(E e);

The first overload takes a boost::exception_ptr (note: not std::exception_ptr) wrapping a concrete exception. The second overload accepts a concrete exception object itself (and internally wraps it in boost::exception_ptr).

When set_exception() is called with an argument of type std::exception_ptr, the second overload is matched, so boost::promise treats std::exception_ptr as the concrete exception type.

The reason this is a problem (besides the inefficiency of wrapping an exception in two layers of exception pointers), is that when the other side (future::get()) throws the exception, the thrown exception object will be the std::exception_ptr itself, not the concrete exception object that it wraps.

For example, suppose the concrete exception type is boost::system::system_error (as is the case in http_async_connection::handle_received_data()). While the client code may be expecting to catch it with a catch clause like this:

catch (boost::system::system_error& e) {
  ...
}

in fact this catch clause will not be matched, because the thrown type was std::exception_ptr.

The fix is simple: when calling boost::promise::set_exception(), don't wrap the concrete exception type with std::make_exception_ptr: just pass the concrete exception object directly.

Activity

  1. deanberris commented on Feb 11, 2018

    @deanberris
    deanberris
    on Feb 11, 2018
    Member
    More actions

    Wow, good catch @HighCommander4 -- do you mind sending a PR to fix these mis-uses of the API? I'd really appreciate it!

  2. HighCommander4 commented on Feb 11, 2018

    @HighCommander4
    HighCommander4
    on Feb 11, 2018
    Author
    More actions

    do you mind sending a PR to fix these mis-uses of the API?

    I can try as soon as I figure out how to build the master branch (currently running into #816).

  3. HighCommander4
    added a commit that references this issue on Feb 14, 2018

    Do not wrap exceptions passed to boost::promise::set_exception in std…

    This issue will close once commit 5701041 is merged into the 'master' branch.
    5701041
  4. deanberris
    added a commit that references this issue on Feb 14, 2018

    Do not wrap exceptions passed to boost::promise::set_exception in std…

    This issue will close once commit 73d4024 is merged into the 'main' branch.
    73d4024
  5. deanberris
    closed this as completedon Feb 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.