You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by br...@apache.org on 2012/12/29 12:36:11 UTC
svn commit: r1426747 - in /subversion/trunk/subversion/bindings/cxxhl:
include/svncxxhl/exception.hpp src/exception.cpp tests/test_exception.cpp
Author: brane
Date: Sat Dec 29 11:36:10 2012
New Revision: 1426747
URL: http://svn.apache.org/viewvc?rev=1426747&view=rev
Log:
Enhance error chain conversion in C++ bindings.
* subversion/bindings/cxxhl/include/svncxxhl/exception.hpp
(subversion::cxxhl::version_1_9_dev::error): Change private constructor to
protected so that the "cancelled" subclass can access it.
(subversion::cxxhl::version_1_9_dev::cancelled): Enable the parent class'
public throw_svn_error factory to create instances of this class.
* subversion/bindings/cxxhl/src/exception.cpp
(subversion::cxxhl::version_1_9_dev::error::thow_svn_error): Refactor
implementation so that we can properly throw "cancelled" exceptions
if the error chain indicates cancellation.
* subversion/bindings/cxxhl/tests/test_exception.cpp: Test throw_svn_error with
both cancellation and regular error chains.
Modified:
subversion/trunk/subversion/bindings/cxxhl/include/svncxxhl/exception.hpp
subversion/trunk/subversion/bindings/cxxhl/src/exception.cpp
subversion/trunk/subversion/bindings/cxxhl/tests/test_exception.cpp
Modified: subversion/trunk/subversion/bindings/cxxhl/include/svncxxhl/exception.hpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxxhl/include/svncxxhl/exception.hpp?rev=1426747&r1=1426746&r2=1426747&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/cxxhl/include/svncxxhl/exception.hpp (original)
+++ subversion/trunk/subversion/bindings/cxxhl/include/svncxxhl/exception.hpp Sat Dec 29 11:36:10 2012
@@ -115,8 +115,10 @@ public:
/** Used internally by the implementation. */
static void throw_svn_error(svn_error_t*);
-private:
+protected:
error(int error_code, detail::error_description* description) throw();
+
+private:
std::vector<message> compile_messages(bool show_traces) const;
int m_errno; /**< The (SVN or APR) error code. */
@@ -125,7 +127,15 @@ private:
detail::error_description* m_description;
};
-class canceled : public error {};
+class cancelled : public error
+{
+ friend void error::throw_svn_error(svn_error_t*);
+
+protected:
+ cancelled(int error_code, detail::error_description* description) throw()
+ : error(error_code, description)
+ {}
+};
} // namespace version_1_9_dev
} // namespace cxxhl
Modified: subversion/trunk/subversion/bindings/cxxhl/src/exception.cpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxxhl/src/exception.cpp?rev=1426747&r1=1426746&r2=1426747&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/cxxhl/src/exception.cpp (original)
+++ subversion/trunk/subversion/bindings/cxxhl/src/exception.cpp Sat Dec 29 11:36:10 2012
@@ -162,6 +162,7 @@ error::error(int error_code, detail::err
void error::throw_svn_error(svn_error_t* err)
{
+ const bool throw_cancelled = (err->apr_err == SVN_ERR_CANCELLED);
detail::error_description* description = NULL;
try
{
@@ -169,28 +170,41 @@ void error::throw_svn_error(svn_error_t*
// the exception unwinder can free them if an allocation fails.
// The private constructor does not increment the refcount
// precisely for this reason.
+
+ shared_ptr nested;
+ shared_ptr* current = &nested;
+
+ for (svn_error_t* next = err->child; next; next = next->child)
+ {
+ description = detail::error_description::create(
+ next->message, next->file, next->line,
+ svn_error__is_tracing_link(next));
+ description->reference();
+ current->reset(new error(next->apr_err, description));
+ description = NULL;
+ current = &(*current)->m_nested;
+ }
+
+ const int apr_err = err->apr_err;
description = detail::error_description::create(
err->message, err->file, err->line,
svn_error__is_tracing_link(err));
description->reference();
- error converted = error(err->apr_err, description);
- description = NULL;
-
- svn_error_t *prev = err;
- error* current = &converted;
- for (err = err->child; err; prev = err, err = err->child)
+ svn_error_clear(err);
+ if (throw_cancelled)
{
- svn_error_clear(prev);
- description = detail::error_description::create(
- err->message, err->file, err->line,
- svn_error__is_tracing_link(err));
- description->reference();
- current->m_nested.reset(new error(err->apr_err, description));
+ cancelled converted = cancelled(apr_err, description);
+ description = NULL;
+ converted.m_nested = nested;
+ throw converted;
+ }
+ else
+ {
+ error converted = error(apr_err, description);
description = NULL;
- current = current->m_nested.get();
+ converted.m_nested = nested;
+ throw converted;
}
- svn_error_clear(prev);
- throw converted;
}
catch (...)
{
Modified: subversion/trunk/subversion/bindings/cxxhl/tests/test_exception.cpp
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxxhl/tests/test_exception.cpp?rev=1426747&r1=1426746&r2=1426747&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/cxxhl/tests/test_exception.cpp (original)
+++ subversion/trunk/subversion/bindings/cxxhl/tests/test_exception.cpp Sat Dec 29 11:36:10 2012
@@ -39,12 +39,52 @@ void trace(const svn::error::message& ms
<< msg.first << ':' << ' ';
std::cout << msg.second << std::endl;
}
+
+void traceall(const char *message, const svn::error& err)
+{
+ typedef svn::error::message_list message_list;
+ std::cout << message << std::endl;
+ std::cout << "Traced Messages:" << std::endl;
+ message_list ml = err.traced_messages();
+ std::for_each(ml.begin(), ml.end(), trace);
+ std::cout << "Just Messages:" << std::endl;
+ ml = err.messages();
+ std::for_each(ml.begin(), ml.end(), trace);
+}
} // anonymous namespace
-int main()
+
+bool test_cancel()
{
- apr_initialize();
+ try
+ {
+ svn_error_t* err;
+ err = svn_error_create(SVN_ERR_TEST_FAILED, NULL, "original message");
+ err = svn_error_create(SVN_ERR_BASE, err, "wrapper message");
+ err = svn_error_create(SVN_ERR_CANCELLED, err, NULL);
+ err = svn_error_create(SVN_ERR_CANCELLED, err, NULL);
+ err = svn_error_trace(err);
+ svn::error::throw_svn_error(err);
+ }
+ catch (const svn::cancelled& err)
+ {
+ traceall("Caught: CANCEL", err);
+ return true;
+ }
+ catch (const svn::error& err)
+ {
+ traceall("Caught: ERROR", err);
+ return false;
+ }
+ catch (...)
+ {
+ return false;
+ }
+ return false;
+}
+int test_error()
+{
try
{
svn_error_t* err;
@@ -54,20 +94,36 @@ int main()
err = svn_error_create(SVN_ERR_CANCELLED, err, NULL);
err = svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, err, NULL);
err = svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, err, NULL);
- err = svn_error_create(SVN_ERR_CANCELLED, err, NULL);
err = svn_error_trace(err);
svn::error::throw_svn_error(err);
}
+ catch (const svn::cancelled& err)
+ {
+ traceall("Caught: CANCEL", err);
+ return false;
+ }
catch (const svn::error& err)
{
- typedef svn::error::message_list message_list;
- std::cout << "Traced Messages:" << std::endl;
- message_list ml = err.traced_messages();
- std::for_each(ml.begin(), ml.end(), trace);
- std::cout << "Just Messages:" << std::endl;
- ml = err.messages();
- std::for_each(ml.begin(), ml.end(), trace);
+ traceall("Caught: ERROR", err);
+ return true;
}
+ catch (...)
+ {
+ return false;
+ }
+ return false;
+}
+
+int main()
+{
+ apr_initialize();
+
+ const char *stat = (test_cancel() ? "OK" : "ERROR");
+ std::cerr << "test_cancel .... " << stat << std::endl;
+
+ stat = (test_error() ? "OK" : "ERROR");
+ std::cerr << "test_error ..... " << stat << std::endl;
+ apr_terminate();
return 0;
}