Skip to content

Conversation

@practicalswift
Copy link
Contributor

@practicalswift practicalswift commented Jun 4, 2018

Make strprintf noexcept. Improve the error message given on format string errors.

With this change large parts of the code base (strprintf callers directly or indirectly) are switched from an implicit "might throw tinyformat::format_error" to "will not throw" from a compiler/static analyzer perspective.

Also, reducing the number of unnecessary exceptions thrown increases the signal-to-noise for humans when analyzing potential issues introduced by uncaught exceptions.

These were the conditions that could make strprintf(…) throw tinyformat::format_error prior to this commit:

$ git grep TINYFORMAT_ERROR
src/tinyformat.h:// Error handling: Define TINYFORMAT_ERROR to customize the error handling for
src/tinyformat.h:#define TINYFORMAT_ERROR(reasonString) throw tinyformat::format_error(reasonString)
src/tinyformat.h:#ifndef TINYFORMAT_ERROR
src/tinyformat.h:#   define TINYFORMAT_ERROR(reason) assert(0 && reason)
src/tinyformat.h:        TINYFORMAT_ERROR("tinyformat: Cannot convert from argument type to "
src/tinyformat.h:        TINYFORMAT_ERROR("tinyformat: Not enough conversion specifiers in format string");
src/tinyformat.h:            TINYFORMAT_ERROR("tinyformat: Not enough arguments to read variable width");
src/tinyformat.h:                TINYFORMAT_ERROR("tinyformat: Not enough arguments to read variable precision");
src/tinyformat.h:            TINYFORMAT_ERROR("tinyformat: the %a and %A conversion specs "
src/tinyformat.h:            TINYFORMAT_ERROR("tinyformat: %n conversion spec not supported");
src/tinyformat.h:            TINYFORMAT_ERROR("tinyformat: Conversion spec incorrectly "
src/tinyformat.h:            TINYFORMAT_ERROR("tinyformat: Not enough format arguments");
src/tinyformat.h:        TINYFORMAT_ERROR("tinyformat: Too many conversion specifiers in format string");

@practicalswift practicalswift force-pushed the strprintf-noexcept branch 3 times, most recently from 877a8ee to 0e64579 Compare June 4, 2018 22:15
@Empact
Copy link
Contributor

Empact commented Jun 5, 2018

Mild NACK I prefer noisy failures. If the failures here are burdensome, can you cite some?

@practicalswift
Copy link
Contributor Author

practicalswift commented Jun 5, 2018

@Empact How is this less noisy than before? :-)

-    format(oss, fmt.c_str(), args...);
+    try {
+        tfm::format(oss, fmt.c_str(), args...);
+    } catch (const tinyformat::format_error& fmterr) {
+        fprintf(stderr, "Format error: %s (fmt=\"%s\")\n", fmterr.what(), fmt.c_str());
+        std::terminate();
+    }

@Empact
Copy link
Contributor

Empact commented Jun 5, 2018

Basically, blow up when possible, return a value or log or both when not possible. Make errors as difficult to ignore as possible.

@practicalswift
Copy link
Contributor Author

practicalswift commented Jun 5, 2018

@Empact I agree, but I don't get how this is less noisy. std::terminate() is called earlier :-)

@Empact
Copy link
Contributor

Empact commented Jun 5, 2018

Fair enough, terminate is effectively noisy, but given terminate would be called if the exception were uncaught, ironically, this now makes errors which would have previously been blanket-caught via catch(...) etc a terminate which is a potentially problematic behavior change. But maybe I'm wrong on that? It was called out on me here relative to converting asserts to throw: #13268

FTR I don't like that we have blanket-catches in the codebase, but they're sometimes warranted.

@practicalswift
Copy link
Contributor Author

Hopefully we will have format string linting soon (see separate PR) and perhaps that will allow us to make strprintf(…) noexcept. But I'm not sure std::terminate is the right way to go here in case of formatting errors. Perhaps better to just print an error message to stderr and/or return the error message to the caller? @laanwj, what do you think?

@DrahtBot
Copy link
Contributor

The last travis run for this pull request was 54 days ago and is thus outdated. To trigger a fresh travis build, this pull request should be closed and re-opened.

@DrahtBot
Copy link
Contributor

DrahtBot commented Aug 1, 2018

Note to reviewers: This pull request conflicts with the following ones:

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

@laanwj
Copy link
Member

laanwj commented Aug 31, 2018

I'm going to close this, I don't think this change is really necessary.

@laanwj laanwj closed this Aug 31, 2018
@practicalswift practicalswift deleted the strprintf-noexcept branch April 10, 2021 19:34
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Aug 18, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants