[PATCH] D17778: TypedError for recoverable error handling
David Blaikie via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 14 16:19:57 PDT 2016
dblaikie added inline comments.
================
Comment at: docs/ProgrammersManual.rst:419
@@ +418,3 @@
+ // Try to handle 'M'. If successful, return a success value from
+ // the handler.
+ if (tryToHandle(M))
----------------
Indentation
================
Comment at: include/llvm/Support/Error.h:349-379
@@ +348,33 @@
+
+// Specialization for member functions of the form 'Error (const ErrT&)'.
+template <typename C, typename ErrT>
+class ErrorHandlerTraits<Error (C::*)(ErrT &)>
+ : public ErrorHandlerTraits<Error (&)(ErrT &)> {};
+
+// Specialization for member functions of the form 'Error (const ErrT&) const'.
+template <typename C, typename ErrT>
+class ErrorHandlerTraits<Error (C::*)(ErrT &) const>
+ : public ErrorHandlerTraits<Error (&)(ErrT &)> {};
+
+// Specialization for member functions of the form 'Error (const ErrT&)'.
+template <typename C, typename ErrT>
+class ErrorHandlerTraits<Error (C::*)(const ErrT &)>
+ : public ErrorHandlerTraits<Error (&)(ErrT &)> {};
+
+// Specialization for member functions of the form 'Error (const ErrT&) const'.
+template <typename C, typename ErrT>
+class ErrorHandlerTraits<Error (C::*)(const ErrT &) const>
+ : public ErrorHandlerTraits<Error (&)(ErrT &)> {};
+
+/// Specialization for member functions of the form
+/// 'Error (std::unique_ptr<ErrT>) const'.
+template <typename C, typename ErrT>
+class ErrorHandlerTraits<Error (C::*)(std::unique_ptr<ErrT>)>
+ : public ErrorHandlerTraits<Error (&)(std::unique_ptr<ErrT>)> {};
+
+/// Specialization for member functions of the form
+/// 'Error (std::unique_ptr<ErrT>) const'.
+template <typename C, typename ErrT>
+class ErrorHandlerTraits<Error (C::*)(std::unique_ptr<ErrT>) const>
+ : public ErrorHandlerTraits<Error (&)(std::unique_ptr<ErrT>)> {};
+
----------------
Where's all this get used? Didn't immediately spot any test cases related to member function error handlers.
================
Comment at: include/llvm/Support/Error.h:447-461
@@ +446,17 @@
+
+ // Helper class to log uncaught errors.
+ class LogUncaughtErrorsTo {
+ public:
+ typedef ErrorInfoBase ErrorT;
+ LogUncaughtErrorsTo(raw_ostream &OS) : OS(OS) {}
+ bool appliesTo(ErrorInfoBase &EI) const { return true; }
+ Error operator()(std::unique_ptr<ErrorInfoBase> EI) {
+ EI->log(OS);
+ OS << "\n";
+ return Error();
+ }
+
+ private:
+ raw_ostream &OS;
+ };
+
----------------
Can this not be implemented with a lambda like other handlers? (something about the "appliesTo" functionality?)
================
Comment at: include/llvm/Support/Error.h:616-617
@@ +615,4 @@
+
+ this->~Expected();
+ new (this) Expected(std::move(Other));
+ }
----------------
That feels a tad heavyweight & perhaps nicer to do with just a couple of named functions, but I'm not wedded to the notion.
================
Comment at: unittests/Support/ErrorTest.cpp:148
@@ +147,3 @@
+
+ consumeError(std::move(E));
+ consumeError(std::move(F));
----------------
Might be worth having a consumeError that takes a non-const ref (lvalue ref) so you don't have to add the std::move. Just to make the tests a bit more terse. Seems easy/handy enough.
================
Comment at: unittests/Support/ErrorTest.cpp:181
@@ +180,3 @@
+
+ // Check that named handlers of type 'Error (const Err&)' work.
+ handleAllErrors(make_error<CustomError>(42), handleCustomError);
----------------
Is it worth testing named handlers separately from function objects? Is there anything special going on in the implementation that would make these cases different?
================
Comment at: unittests/Support/ErrorTest.cpp:257-272
@@ +256,18 @@
+
+ handleAllErrors(std::move(E),
+ [&](const CustomSubError &SE) {
+ CustomErrorInfo2 = SE.getInfo();
+ CustomErrorExtraInfo = SE.getExtraInfo();
+ return Error();
+ },
+ [&](const CustomError &CE) {
+ // Assert that the CustomError instance above is handled
+ // before the
+ // CustomSubError - joinErrors should preserve error
+ // ordering.
+ if (CustomErrorInfo2 != 0)
+ abort();
+ CustomErrorInfo1 = CE.getInfo();
+ return Error();
+ });
+
----------------
Probably worth bringing this sort of formatting to the attention of djasper and the clang-format folks, see if we can do anything better here
================
Comment at: unittests/Support/ErrorTest.cpp:261
@@ +260,3 @@
+ CustomErrorExtraInfo = SE.getExtraInfo();
+ return Error();
+ },
----------------
why are the error handlers returning errors? (maybe I'll figure this out before I finish reviewing the patch...)
So I see from the docs this is for dynamically unhandled errors - do you have a use case in mind for that already? Could we defer adding it until we do? Might it be worth allowing void returning handlers for the common case of a handler that won't dynamically fail to handle the error?
================
Comment at: unittests/Support/ErrorTest.cpp:268-269
@@ +267,4 @@
+ // ordering.
+ if (CustomErrorInfo2 != 0)
+ abort();
+ CustomErrorInfo1 = CE.getInfo();
----------------
Presumably these two lines should be an EXPECT_ or ASSERT_ style macro, rather than an anonymous abort()?
================
Comment at: unittests/Support/ErrorTest.cpp:279-287
@@ +278,11 @@
+
+ // Test consumeError for both success and error cases.
+ {{Error E;
+ consumeError(std::move(E));
+}
+{
+ Error E = make_error<CustomError>(7);
+ consumeError(std::move(E));
+}
+}
+
----------------
what's going on witmh the indentation and brace matching here?
================
Comment at: unittests/Support/ErrorTest.cpp:320
@@ +319,3 @@
+
+// Test that we can return values from handleErrors.
+{
----------------
Test case might be easier to follow if the value returned was not itself another error (to demonstrate that it's entirely independent - maybe a string or unique_ptr<int> if you want a move-only thing, etc)
================
Comment at: unittests/Support/ErrorTest.cpp:382-385
@@ +381,6 @@
+ {
+ auto DropUncheckedExpected = []() {
+ Expected<int> A = make_error<CustomError>(42);
+ };
+ EXPECT_DEATH(DropUncheckedExpected(),
+ "Program aborted due to an unhandled Error:")
----------------
You can just roll the contents of the lambda into the EXPECT_DEATH:
EXPECT_DEATH({ Expected<int> A = make_error<CustomError>(42); }, ... );
http://reviews.llvm.org/D17778
More information about the llvm-commits
mailing list