used new exception classes

pull/40/head
Matchman Green 2012-05-13 15:27:58 +08:00
parent 66e7783a9c
commit 8ced12d5a1
19 changed files with 194 additions and 94 deletions

View File

@ -18,9 +18,15 @@
*/
#include "drive/Drive.hh"
#include "protocol/OAuth2.hh"
#include "protocol/Json.hh"
#include "bfd/Backtrace.hh"
#include "util/Exception.hh"
#include <boost/exception/all.hpp>
#include <cassert>
#include <cstdlib>
#include <fstream>
@ -137,8 +143,18 @@ int main( int argc, char **argv )
return -1;
}
OAuth2 token( refresh_token, client_id, client_secret ) ;
Drive drive( token ) ;
try
{
OAuth2 token( refresh_token, client_id, client_secret ) ;
Drive drive( token ) ;
}
catch ( gr::Exception& e )
{
std::cerr
<< "exception: " << e.what() << std::endl
<< *boost::get_error_info<gr::expt::BacktraceInfo>( e )
<< std::endl ;
}
return 0 ;
}

View File

@ -19,6 +19,7 @@ if ( BFD_FOUND )
file( GLOB OPT_SRC
src/bfd/*.cc
)
add_definitions( -DHAVE_BFD )
endif ( BFD_FOUND )
@ -52,7 +53,11 @@ file (GLOB LIBGRIVE_SRC
src/xml/*.cc
)
add_definitions( -DVERSION="${GRIVE_VERSION}" -DTEST_DATA="${libgrive_SOURCE_DIR}/test/data/" )
add_definitions(
-DVERSION="${GRIVE_VERSION}"
-DTEST_DATA="${libgrive_SOURCE_DIR}/test/data/"
-DSRC_DIR="${libgrive_SOURCE_DIR}/src"
)
add_library( grive SHARED ${LIBGRIVE_SRC} ${OPT_SRC} )

View File

@ -138,10 +138,7 @@ void SymbolInfo::BacktraceInfo::Callback( bfd *abfd, asection *section,
std::size_t SymbolInfo::Backtrace( void **stack, std::size_t count )
{
std::cerr << "begin backtrace" << std::endl ;
std::size_t a = ::backtrace( stack, count ) ;
std::cerr << "end backtrace" << std::endl ;
return a ;
}
@ -152,12 +149,10 @@ void SymbolInfo::PrintTrace( void *addr, std::ostream& os, std::size_t idx )
this, addr, 0, 0, 0, false
} ;
std::cerr << "begin bfd" << std::endl ;
Dl_info sym ;
bfd_map_over_sections( m_impl->m_bfd,
&SymbolInfo::BacktraceInfo::Callback,
&btinfo ) ;
std::cerr << "end bfd" << std::endl ;
if ( btinfo.m_is_found )
{

View File

@ -20,6 +20,7 @@
#pragma once
#include "Entry.hh"
#include "util/Exception.hh"
#include "util/Function.hh"
#include <string>
@ -56,7 +57,9 @@ public :
void ForEachFile(
Function<void(const std::string&)> callback,
const std::string& prefix = "." ) ;
struct Error : virtual Exception {} ;
private :
Entry m_entry ;

View File

@ -20,6 +20,7 @@
#pragma once
#include "Collection.hh"
#include "util/Exception.hh"
#include <string>
#include <vector>
@ -48,6 +49,8 @@ public :
Drive( OAuth2& auth ) ;
~Drive( ) ;
struct Error : virtual Exception {} ;
private :
void UpdateFile( Entry& file, const Collection& parent, http::Agent *http ) ;

View File

@ -122,15 +122,15 @@ std::string Entry::ParentHref() const
return m_parent_href ;
}
void Entry::Download( gr::http::Agent* http, const Path& file, const http::Headers& auth ) const
void Entry::Download( http::Agent* http, const Path& file, const http::Headers& auth ) const
{
gr::Download dl( file.Str(), Download::NoChecksum() ) ;
http::Download dl( file.Str(), http::Download::NoChecksum() ) ;
long r = http->Get( m_content_src, &dl, auth ) ;
if ( r <= 400 )
os::SetFileTime( file, m_server_modified ) ;
}
bool Entry::Upload( gr::http::Agent* http, std::streambuf *file, const http::Headers& auth )
bool Entry::Upload( http::Agent* http, std::streambuf *file, const http::Headers& auth )
{
// upload link missing means that file is read only
if ( m_upload_link.empty() )

View File

@ -63,9 +63,9 @@ public :
const std::vector<std::string>& ParentHrefs() const ;
void Download( gr::http::Agent* http, const Path& file, const http::Headers& auth ) const ;
bool Upload( gr::http::Agent* http, std::streambuf *file, const http::Headers& auth ) ;
void Delete( gr::http::Agent* http, const gr::http::Headers& auth ) ;
void Download( http::Agent* http, const Path& file, const http::Headers& auth ) const ;
bool Upload( http::Agent* http, std::streambuf *file, const http::Headers& auth ) ;
void Delete( http::Agent* http, const gr::http::Headers& auth ) ;
void Swap( Entry& e ) ;

View File

@ -20,7 +20,7 @@
#include "Agent.hh"
#include "Download.hh"
#include "Exception.hh"
#include "Error.hh"
#include "Receivable.hh"
// dependent libraries
@ -138,14 +138,13 @@ long Agent::ExecCurl(
long http_code = 0;
::curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
if ( curl_code != CURLE_OK )
if ( curl_code != CURLE_OK || http_code >= 400 )
{
throw Exception( curl_code, http_code, m_pimpl->error ) ;
}
else if (http_code >= 400 )
{
std::cout << "http error " << http_code << std::endl ;
throw Exception( curl_code, http_code, m_pimpl->error ) ;
throw Error()
<< CurlCode( curl_code )
<< HttpResponse( http_code )
<< expt::ErrMsg( m_pimpl->error ) ;
}
return http_code ;

View File

@ -20,6 +20,8 @@
#include "Download.hh"
// #include "util/SignalHandler.hh"
#include "Error.hh"
#include <openssl/evp.h>
#include <cassert>
@ -28,7 +30,7 @@
#include <signal.h>
namespace gr {
namespace gr { namespace http {
Download::Download( const std::string& filename ) :
m_file( filename.c_str(), std::ios::out | std::ios::binary ),
@ -38,10 +40,10 @@ Download::Download( const std::string& filename ) :
throw std::bad_alloc() ;
if ( ::EVP_DigestInit_ex( m_mdctx, ::EVP_md5(), 0 ) != 1 )
throw std::runtime_error( "cannot create MD5 digest context" ) ;
throw Error() << expt::ErrMsg( "cannot create MD5 digest context" ) ;
if ( !m_file )
throw std::runtime_error( "cannot open file " + filename + " for writing" ) ;
throw Error() << expt::ErrMsg( "cannot open file " + filename + " for writing" ) ;
}
Download::Download( const std::string& filename, NoChecksum ) :
@ -49,7 +51,7 @@ Download::Download( const std::string& filename, NoChecksum ) :
m_mdctx( 0 )
{
if ( !m_file )
throw std::runtime_error( "cannot open file " + filename + " for writing" ) ;
throw Error() << expt::ErrMsg( "cannot open file " + filename + " for writing" ) ;
}
Download::~Download( )
@ -77,7 +79,7 @@ std::string Download::Finish() const
result.resize( size ) ;
if ( ::EVP_DigestFinal_ex( m_mdctx, reinterpret_cast<unsigned char*>(&result[0]), &size ) != 1 )
throw std::runtime_error( "cannot calculate checksum" ) ;
throw Error() << expt::ErrMsg( "cannot calculate checksum" ) ;
result.resize( size ) ;
}
@ -108,4 +110,4 @@ std::size_t Download::OnData( void *data, std::size_t count )
return m_file.rdbuf()->sputn( reinterpret_cast<char*>(data), count ) ;
}
} // end of namespace
} } // end of namespace

View File

@ -26,7 +26,7 @@
#include <openssl/evp.h>
namespace gr {
namespace gr { namespace http {
class Download : public http::Receivable
{
@ -48,4 +48,4 @@ private :
EVP_MD_CTX *m_mdctx ;
} ;
} // end of namespace
} } // end of namespace

View File

@ -1,35 +0,0 @@
/*
grive: an GPL program to sync a local directory with Google Drive
Copyright (C) 2012 Wan Wai Ho
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation version 2
of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#pragma once
#include <stdexcept>
namespace gr { namespace http {
class Exception : public std::runtime_error
{
public :
Exception( int curl_code, int http_code, const char *err_buf ) ;
private :
static std::string Format( int curl_code, int http_code, const char *err_buf ) ;
} ;
} } // end of namespace

View File

@ -25,7 +25,6 @@
#include <cassert>
#include <iostream>
#include <sstream>
#include <stdexcept>
namespace gr {
@ -33,7 +32,7 @@ Json::Json( ) :
m_json( ::json_object_new_object() )
{
if ( m_json == 0 )
throw std::runtime_error( "cannot create json object" ) ;
throw Error() << expt::ErrMsg( "cannot create json object" ) ;
}
template <>
@ -41,7 +40,7 @@ Json::Json( const std::string& str ) :
m_json( ::json_object_new_string( str.c_str() ) )
{
if ( m_json == 0 )
throw std::runtime_error( "cannot create json string \"" + str + "\"" ) ;
throw Error() << expt::ErrMsg( "cannot create json string \"" + str + "\"" ) ;
// paranoid check
assert( ::json_object_get_string( m_json ) == str ) ;
@ -51,7 +50,7 @@ Json Json::Parse( const std::string& str )
{
struct json_object *json = ::json_tokener_parse( str.c_str() ) ;
if ( json == 0 )
throw std::runtime_error( "json parse error" ) ;
throw Error() << expt::ErrMsg( "json parse error" ) ;
return Json( json, NotOwned() ) ;
}
@ -103,7 +102,7 @@ Json Json::operator[]( const std::string& key ) const
struct json_object *j = ::json_object_object_get( m_json, key.c_str() ) ;
if ( j == 0 )
throw std::runtime_error( "key: " + key + " is not found in object" ) ;
throw Error() << expt::ErrMsg( "key: " + key + " is not found in object" ) ;
return Json( j ) ;
}
@ -117,7 +116,7 @@ Json Json::operator[]( const std::size_t& idx ) const
{
std::ostringstream ss ;
ss << "index " << idx << " is not found in array" ;
throw std::runtime_error( ss.str() ) ;
throw Error() << expt::ErrMsg( ss.str() ) ;
}
return Json( j ) ;
@ -241,7 +240,7 @@ Json Json::FindInArray( const std::string& key, const std::string& value ) const
if ( item.Has(key) && item[key].As<std::string>() == value )
return item ;
}
throw std::runtime_error( "cannot find " + key + " = " + value + " in array" ) ;
throw Error() << expt::ErrMsg( "cannot find " + key + " = " + value + " in array" ) ;
}
bool Json::FindInArray( const std::string& key, const std::string& value, Json& result ) const
@ -251,7 +250,7 @@ bool Json::FindInArray( const std::string& key, const std::string& value, Json&
result = FindInArray( key, value ) ;
return true ;
}
catch ( std::runtime_error& )
catch ( Error& )
{
return false ;
}

View File

@ -19,6 +19,8 @@
#pragma once
#include "util/Exception.hh"
#include <string>
#include <map>
#include <vector>
@ -33,6 +35,8 @@ public :
typedef std::map<std::string, Json> Object ;
typedef std::vector<Json> Array ;
struct Error : virtual Exception {} ;
public :
template <typename T>
explicit Json( const T& val ) ;

View File

@ -17,22 +17,37 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "Exception.hh"
#include "util/Exception.hh"
#include "bfd/Backtrace.hh"
#include "bfd/Debug.hh"
#include <boost/exception/all.hpp>
#include <cstdlib>
#include <iterator>
#include <sstream>
namespace gr { namespace http {
namespace gr {
Exception::Exception( int curl_code, int http_code, const char *err_buf )
: runtime_error( Format( curl_code, http_code, err_buf ) )
class Backtrace ;
Exception::Exception( )
{
#ifdef HAVE_BFD
*this << expt::BacktraceInfo( Backtrace() ) ;
#endif
}
std::string Exception::Format( int curl_code, int http_code, const char *err_buf )
const char* Exception::what() const throw()
{
std::ostringstream ss ;
ss << "CURL code = " << curl_code << " HTTP code = " << http_code << " (" << err_buf << ")" ;
return ss.str() ;
if ( const std::string *s = boost::get_error_info<expt::ErrMsg>(*this) )
return s->c_str() ;
else
{
static const char unknown[] = "unknown" ;
return unknown ;
}
}
} } // end of namespace
} // end of namespace

View File

@ -0,0 +1,85 @@
/*
grive: an GPL program to sync a local directory with Google Drive
Copyright (C) 2012 Wan Wai Ho
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation version 2
of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#pragma once
#include <boost/exception/exception.hpp>
#include <boost/exception/info.hpp>
#include <typeinfo>
#include <exception>
#include <string>
namespace gr {
class Backtrace ;
/** \defgroup exception Exception Classes
*/
/// base class for exception in libpdfdoc
/** \ingroup exception
This class is the base class for all exception class in libpdfdoc.
*/
struct Exception :
virtual public std::exception,
virtual public boost::exception
{
Exception( ) ;
const char* what() const throw() ;
} ;
struct FileError : virtual Exception {} ;
/// Parse error exception.
/** \ingroup exception
This exception will be thrown when there is a parse error when reading
a PDF file.
*/
struct ParseError : virtual Exception {} ;
/// Invalid type exception.
/** \ingroup exception
This exception will be thrown when the Object cannot convert its
underlying data to a specific type. The what() member function will
describe the expected and actual type of the data.
*/
struct BadType : virtual Exception {} ;
struct Unsupported : virtual Exception {} ;
// Exception informations
namespace expt
{
// back-trace information. should be present for all exceptions
typedef boost::error_info<struct BacktraceTag, Backtrace> BacktraceInfo ;
// generic error message
typedef boost::error_info<struct MsgTag, std::string> ErrMsg ;
// errno as in C
typedef boost::error_info<struct ErrorNumberTag, int> ErrorNumber ;
// the filename of the file that caused the error
typedef boost::error_info<struct FileNameTag, std::string> FileName ;
}
} // end of namespace

View File

@ -20,11 +20,11 @@
#include "OS.hh"
#include "DateTime.hh"
#include "Exception.hh"
#include "Path.hh"
#include <stdexcept>
// OS specific headers
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
@ -50,7 +50,13 @@ DateTime FileMTime( const std::string& filename )
{
struct stat s = {} ;
if ( ::stat( filename.c_str(), &s ) != 0 )
throw std::runtime_error( "cannot get file attribute of " + filename ) ;
{
// save errno to prevend overwritten later
int err_num = errno ;
throw Exception()
<< expt::ErrMsg( "cannot get file attribute of " + filename )
<< expt::ErrorNumber( err_num ) ;
}
#if defined __APPLE__ && defined __DARWIN_64_BIT_INO_T
return DateTime( s.st_mtimespec.tv_sec, s.st_mtimespec.tv_nsec ) ;
@ -68,7 +74,7 @@ void SetFileTime( const std::string& filename, const DateTime& t )
{
struct timeval tvp[2] = { t.Tv(), t.Tv() } ;
if ( ::utimes( filename.c_str(), tvp ) != 0 )
throw std::runtime_error( "cannot set file time" ) ;
throw expt::ErrMsg( "cannot set file time" ) ;
}
} } // end of namespaces

View File

@ -18,13 +18,14 @@
*/
#include "Node.hh"
#include "Error.hh"
#include "NodeSet.hh"
#include <algorithm>
#include <cassert>
#include <functional>
#include <iterator>
#include <stdexcept>
// debugging
#include <iostream>
@ -91,7 +92,7 @@ public :
// cannot allow duplicate attribute nodes
if ( child->m_type == attr && p.first != p.second )
throw std::runtime_error( "duplicate attribute " + child->m_name ) ;
throw Error() << expt::ErrMsg( "duplicate attribute " + child->m_name ) ;
vec.insert( p.second, child ) ;
}

View File

@ -19,8 +19,9 @@
#include "NodeSet.hh"
#include "Error.hh"
#include <algorithm>
#include <stdexcept>
#include <iostream>
@ -123,7 +124,7 @@ NodeSet NodeSet::operator[]( const std::string& name ) const
Node NodeSet::front() const
{
if ( empty() )
throw std::runtime_error( "empty node set" ) ;
throw Error() << expt::ErrMsg( "empty node set" ) ;
return *m_first ;
}

View File

@ -18,6 +18,8 @@
*/
#include "TreeBuilder.hh"
#include "Error.hh"
#include "Node.hh"
#include <expat.h>
@ -25,7 +27,6 @@
#include <cassert>
#include <iostream>
#include <fstream>
#include <stdexcept>
namespace gr { namespace xml {
@ -68,7 +69,7 @@ Node TreeBuilder::ParseFile( const std::string& file )
void TreeBuilder::ParseData( const char *data, std::size_t count, bool last )
{
if ( ::XML_Parse( m_impl->psr, data, count, last ) == 0 )
throw std::runtime_error( "XML parse error" ) ;
throw Error() << expt::ErrMsg( "XML parse error" ) ;
}
Node TreeBuilder::Parse( const std::string& xml )
@ -84,7 +85,7 @@ Node TreeBuilder::Result() const
assert( m_impl->stack.size() == 1 ) ;
if ( m_impl->stack.front().size() != 1 )
throw std::runtime_error( "invalid node" ) ;
throw Error() << expt::ErrMsg( "invalid node" ) ;
return *m_impl->stack.front().begin() ;
}