tinyformat: Add format_no_throw #15926

pull MarcoFalke wants to merge 2 commits into bitcoin:master from MarcoFalke:1904-tinyformatNoThrow changing 3 files +55 −25
  1. MarcoFalke commented at 6:02 pm on April 30, 2019: member

    This adds a tinyformat::format_no_throw that (on error) returns the format string with the error message. format_no_throw is currently only used in logging, but can be used by other modules after this patch.

    The fist commit reverts some style-changes that have been made to tinyformat, which is to be treated like a “subtree”, so style-fixes should go upstream and are not acceptable in Bitcoin Core.

  2. MarcoFalke added the label Refactoring on Apr 30, 2019
  3. laanwj commented at 6:17 pm on April 30, 2019: member
    Are you intending to use this in other places than logging? If not, I’d prefer to keep bitcoin core specific code outside tinyformat.h. ACK on reverting the style changes.
  4. MarcoFalke commented at 6:20 pm on April 30, 2019: member
    Yes, the gui should probably use it for messages, so that at least the generic error is logged (as opposed to only “A tfm error occured!”)
  5. MarcoFalke force-pushed on Apr 30, 2019
  6. in src/tinyformat.h:1070 in a157831620 outdated
    1067-    return oss.str();
    1068+    return format(fmt.c_str(), args...);
    1069+}
    1070+
    1071+template <typename... Args>
    1072+std::string format_no_throw(const std::string& fmt, const Args&... args)
    


    practicalswift commented at 6:50 am on May 1, 2019:
    Add noexcept to make the “no throw” part of the contract and thus understandable also for the compiler :-)

    MarcoFalke commented at 1:46 pm on May 1, 2019:
    How can I (or the compiler) be sure that no other exceptions (e.g. std::out_of_range) are thrown?

    practicalswift commented at 4:20 pm on May 2, 2019:

    There is really no shortcut here AFAIK: reading + reasoning would be required :-)

    Do you see any places where e.g. std::out_of_range could be thrown that is reachable from format? Beyond the already handled format_error.

    The contract of tinyformat is that format_error is the only exception thrown?


    sipa commented at 4:34 pm on May 2, 2019:
    I think the point of adding “noexcept” isn’t so much because you know a function won’t throw; it’s that you know that exceptions thrown anyway can be regarded as fatal errors.

    practicalswift commented at 4:48 pm on May 2, 2019:

    MarcoFalke commented at 5:59 pm on May 2, 2019:
    I see, so it is equivalent to std::terminate. I think I will leave that for later, as I am not sure that immediate termination is better than offering the gui or daemon to catch the exception

    practicalswift commented at 7:38 am on May 3, 2019:

    I think it is unwise to use function naming (format_no_throw) which gives the caller the impression that the contract is that the function cannot throw if we’re not willing to back that with a noexcept guarantee.

    I think we should either 1.) handle any non-fatal exception within format_no_throw and mark it noexcept, or 2.) remove the _no_throw suffix.


    promag commented at 10:52 am on June 9, 2019:
    Maybe add a comment like This function wraps format() to return error messages instead of throwing format_error. All other format() exceptions are thrown away.

    MarcoFalke commented at 7:03 am on June 10, 2019:
    Added a comment
  7. in src/logging.h:138 in a157831620 outdated
    139-        } catch (tinyformat::format_error& fmterr) {
    140-            /* Original format string will have newline so don't add one here */
    141-            log_msg = "Error \"" + std::string(fmterr.what()) + "\" while formatting log message: " + fmt;
    142-        }
    143-        LogInstance().LogPrintStr(log_msg);
    144+        LogInstance().LogPrintStr(tfm::format_no_throw(fmt, args...));
    


    practicalswift commented at 7:11 am on May 1, 2019:

    I suggest making LogPrintf noexcept, but before doing so note that the following call chain is triggered here (also before this PR):

    • LogPrintStrLogTimestampStrFormatISO8601DateTimestrprintf

    Generally strprintf may throw tinyformat::format_error.

    In the case of the call FormatISO8601DateTime I don’t think that is possible since the format string is well formed. However, that is not understood by the compiler which currently must assume that FormatISO8601DateTime can throw.

    I suggest handling the (non-reachable) tinyformat::format_error explicitly in FormatISO8601DateTime and then making that function noexcept too. (Should be done also for its companion FormatISO8601Date).

    So in summary my suggestion is to:

    • Handle tinyformat::format_error in FormatISO8601DateTime and FormatISO8601Date
    • Add noexcept to FormatISO8601DateTime, FormatISO8601Date and LogPrintf
  8. MarcoFalke force-pushed on May 1, 2019
  9. DrahtBot commented at 2:54 pm on May 9, 2019: member

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Conflicts

    No conflicts as of last run.

  10. DrahtBot added the label Needs rebase on May 14, 2019
  11. tinyformat: Undo style-fixes that should go upstream instead fa1bf40576
  12. MarcoFalke force-pushed on May 14, 2019
  13. DrahtBot removed the label Needs rebase on May 14, 2019
  14. tinyformat: Add format_no_throw fa7e309ca1
  15. MarcoFalke force-pushed on Jun 10, 2019
  16. MarcoFalke closed this on Jun 14, 2019

  17. MarcoFalke deleted the branch on Jun 14, 2019
  18. MarcoFalke commented at 9:55 am on June 14, 2019: member
    We have a linter to check the number of arguments, so I guess this isn’t much needed
  19. DrahtBot locked this on Dec 16, 2021

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-11-21 12:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me