mirror of
https://github.com/matrix-construct/construct
synced 2024-11-15 14:31:11 +01:00
ircd::db: Simplify/Consolidate error hierarchy.
This commit is contained in:
parent
aa166d0c5d
commit
2876398c04
4 changed files with 224 additions and 69 deletions
|
@ -38,6 +38,7 @@ namespace rocksdb
|
|||
struct SstFileWriter;
|
||||
struct TableProperties;
|
||||
struct LogFile;
|
||||
struct Status;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
namespace ircd::db
|
||||
{
|
||||
struct init;
|
||||
struct error;
|
||||
struct gopts;
|
||||
struct sopts;
|
||||
struct cell;
|
||||
|
@ -24,26 +25,6 @@ namespace ircd::db
|
|||
struct database;
|
||||
struct options;
|
||||
|
||||
// Errors for the database subsystem. The exceptions that use _HIDENAME
|
||||
// are built from RocksDB errors which already have an info string with
|
||||
// an included name.
|
||||
//
|
||||
IRCD_EXCEPTION(ircd::error, error)
|
||||
IRCD_EXCEPTION(error, not_found)
|
||||
IRCD_EXCEPTION(error, schema_error)
|
||||
IRCD_EXCEPTION_HIDENAME(error, corruption)
|
||||
IRCD_EXCEPTION_HIDENAME(error, not_supported)
|
||||
IRCD_EXCEPTION_HIDENAME(error, invalid_argument)
|
||||
IRCD_EXCEPTION_HIDENAME(error, io_error)
|
||||
IRCD_EXCEPTION_HIDENAME(error, merge_in_progress)
|
||||
IRCD_EXCEPTION_HIDENAME(error, incomplete)
|
||||
IRCD_EXCEPTION_HIDENAME(error, shutdown_in_progress)
|
||||
IRCD_EXCEPTION_HIDENAME(error, timed_out)
|
||||
IRCD_EXCEPTION_HIDENAME(error, aborted)
|
||||
IRCD_EXCEPTION_HIDENAME(error, busy)
|
||||
IRCD_EXCEPTION_HIDENAME(error, expired)
|
||||
IRCD_EXCEPTION_HIDENAME(error, try_again)
|
||||
|
||||
// db subsystem has its own logging facility
|
||||
extern struct log::log log;
|
||||
|
||||
|
@ -71,6 +52,7 @@ namespace ircd::db
|
|||
#include "database/snapshot.h"
|
||||
#include "database/sst.h"
|
||||
#include "database/wal.h"
|
||||
#include "error.h"
|
||||
#include "cache.h"
|
||||
#include "opts.h"
|
||||
#include "column.h"
|
||||
|
|
91
include/ircd/db/error.h
Normal file
91
include/ircd/db/error.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
// Matrix Construct
|
||||
//
|
||||
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice is present in all copies. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
#pragma once
|
||||
#define HAVE_IRCD_DB_ERROR_H
|
||||
|
||||
namespace ircd::db
|
||||
{
|
||||
struct error;
|
||||
}
|
||||
|
||||
/// Database error. For most catchers of this error outside of the db:: system,
|
||||
/// the formatted what() message will be sufficient. The codes are not useful
|
||||
/// outside of db::. A common error `not_found` has its own subtype to be
|
||||
/// caught independently;
|
||||
///
|
||||
struct ircd::db::error
|
||||
:ircd::error
|
||||
{
|
||||
struct not_found;
|
||||
|
||||
protected:
|
||||
static const rocksdb::Status _no_code_;
|
||||
|
||||
public:
|
||||
uint8_t code {0};
|
||||
uint8_t subcode {0};
|
||||
uint8_t severity {0};
|
||||
|
||||
error(generate_skip_t,
|
||||
const rocksdb::Status &);
|
||||
|
||||
explicit
|
||||
error(const rocksdb::Status &);
|
||||
|
||||
IRCD_OVERLOAD(internal)
|
||||
error(internal_t,
|
||||
const rocksdb::Status &s,
|
||||
const string_view &fmt,
|
||||
const va_rtti &ap);
|
||||
|
||||
template<class... args>
|
||||
error(const rocksdb::Status &s,
|
||||
const string_view &fmt,
|
||||
args&&... a)
|
||||
:error
|
||||
{
|
||||
internal, s, fmt, va_rtti{std::forward<args>(a)...}
|
||||
}{}
|
||||
|
||||
template<class... args>
|
||||
error(const string_view &fmt,
|
||||
args&&... a)
|
||||
:error
|
||||
{
|
||||
internal, _no_code_, fmt, va_rtti{std::forward<args>(a)...}
|
||||
}{}
|
||||
};
|
||||
|
||||
namespace ircd::db
|
||||
{
|
||||
using not_found = error::not_found;
|
||||
}
|
||||
|
||||
/// Common error `not_found` has its own subtype to be caught independently;
|
||||
/// it may contain a more limited what() (or none at all) as an optimization.
|
||||
///
|
||||
struct ircd::db::error::not_found
|
||||
:error
|
||||
{
|
||||
protected:
|
||||
static const rocksdb::Status _not_found_;
|
||||
|
||||
public:
|
||||
template<class... args>
|
||||
not_found(const string_view &fmt,
|
||||
args&&... a)
|
||||
:error
|
||||
{
|
||||
_not_found_, fmt, std::forward<args>(a)...
|
||||
}{}
|
||||
|
||||
not_found();
|
||||
};
|
179
ircd/db.cc
179
ircd/db.cc
|
@ -1371,14 +1371,9 @@ try
|
|||
d->GetLatestSequenceNumber()
|
||||
};
|
||||
}
|
||||
catch(const corruption &e)
|
||||
catch(const error &e)
|
||||
{
|
||||
throw corruption
|
||||
{
|
||||
"Corruption for '%s' (%s). Try restarting with the -pitrecdb command line option",
|
||||
this->name,
|
||||
e.what()
|
||||
};
|
||||
throw;
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
|
@ -1535,7 +1530,7 @@ ircd::db::database::operator[](const string_view &name)
|
|||
{
|
||||
const auto it{column_names.find(name)};
|
||||
if(unlikely(it == std::end(column_names)))
|
||||
throw schema_error
|
||||
throw not_found
|
||||
{
|
||||
"'%s': column '%s' is not available or specified in schema",
|
||||
this->name,
|
||||
|
@ -1555,7 +1550,7 @@ try
|
|||
}
|
||||
catch(const std::out_of_range &e)
|
||||
{
|
||||
throw schema_error
|
||||
throw not_found
|
||||
{
|
||||
"'%s': column id[%u] is not available or specified in schema",
|
||||
this->name,
|
||||
|
@ -1569,7 +1564,7 @@ const
|
|||
{
|
||||
const auto it{column_names.find(name)};
|
||||
if(unlikely(it == std::end(column_names)))
|
||||
throw schema_error
|
||||
throw not_found
|
||||
{
|
||||
"'%s': column '%s' is not available or specified in schema",
|
||||
this->name,
|
||||
|
@ -1589,7 +1584,7 @@ const try
|
|||
}
|
||||
catch(const std::out_of_range &e)
|
||||
{
|
||||
throw schema_error
|
||||
throw not_found
|
||||
{
|
||||
"'%s': column id[%u] is not available or specified in schema",
|
||||
this->name,
|
||||
|
@ -9167,7 +9162,7 @@ ircd::db::row::operator[](const string_view &column)
|
|||
{
|
||||
const auto it(find(column));
|
||||
if(unlikely(it == end()))
|
||||
throw schema_error
|
||||
throw not_found
|
||||
{
|
||||
"column '%s' not specified in the descriptor schema", column
|
||||
};
|
||||
|
@ -9181,7 +9176,7 @@ const
|
|||
{
|
||||
const auto it(find(column));
|
||||
if(unlikely(it == end()))
|
||||
throw schema_error
|
||||
throw not_found
|
||||
{
|
||||
"column '%s' not specified in the descriptor schema", column
|
||||
};
|
||||
|
@ -10994,11 +10989,133 @@ ircd::db::ticker(const rocksdb::Cache &cache,
|
|||
zero;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// error.h
|
||||
//
|
||||
|
||||
//
|
||||
// error::not_found
|
||||
//
|
||||
|
||||
decltype(ircd::db::error::not_found::_not_found_)
|
||||
ircd::db::error::not_found::_not_found_
|
||||
{
|
||||
rocksdb::Status::NotFound()
|
||||
};
|
||||
|
||||
//
|
||||
// error::not_found::not_found
|
||||
//
|
||||
|
||||
ircd::db::error::not_found::not_found()
|
||||
:error
|
||||
{
|
||||
generate_skip, _not_found_
|
||||
}
|
||||
{
|
||||
strlcpy(buf, "NotFound");
|
||||
}
|
||||
|
||||
//
|
||||
// error
|
||||
//
|
||||
|
||||
decltype(ircd::db::error::_no_code_)
|
||||
ircd::db::error::_no_code_
|
||||
{
|
||||
rocksdb::Status::OK()
|
||||
};
|
||||
|
||||
//
|
||||
// error::error
|
||||
//
|
||||
|
||||
ircd::db::error::error(internal_t,
|
||||
const rocksdb::Status &s,
|
||||
const string_view &fmt,
|
||||
const va_rtti &ap)
|
||||
:error
|
||||
{
|
||||
s
|
||||
}
|
||||
{
|
||||
const string_view &msg{buf};
|
||||
const mutable_buffer remain
|
||||
{
|
||||
buf + size(msg), sizeof(buf) - size(msg)
|
||||
};
|
||||
|
||||
fmt::vsprintf
|
||||
{
|
||||
remain, fmt, ap
|
||||
};
|
||||
}
|
||||
|
||||
ircd::db::error::error(const rocksdb::Status &s)
|
||||
:error
|
||||
{
|
||||
generate_skip, s
|
||||
}
|
||||
{
|
||||
fmt::sprintf
|
||||
{
|
||||
buf, "%s (%u:%u): %s (%u)",
|
||||
s.getState(),
|
||||
this->code,
|
||||
this->subcode,
|
||||
reflect(s.severity()),
|
||||
this->severity,
|
||||
};
|
||||
}
|
||||
|
||||
ircd::db::error::error(generate_skip_t,
|
||||
const rocksdb::Status &s)
|
||||
:ircd::error
|
||||
{
|
||||
generate_skip
|
||||
}
|
||||
,code
|
||||
{
|
||||
s.code()
|
||||
}
|
||||
,subcode
|
||||
{
|
||||
s.subcode()
|
||||
}
|
||||
,severity
|
||||
{
|
||||
s.severity()
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Misc
|
||||
//
|
||||
|
||||
//
|
||||
// throw_on_error
|
||||
//
|
||||
|
||||
ircd::db::throw_on_error::throw_on_error(const rocksdb::Status &status)
|
||||
{
|
||||
using rocksdb::Status;
|
||||
|
||||
switch(status.code())
|
||||
{
|
||||
case Status::kOk:
|
||||
return;
|
||||
|
||||
case Status::kNotFound:
|
||||
throw not_found{};
|
||||
|
||||
default:
|
||||
throw error{status};
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string>
|
||||
ircd::db::column_names(const std::string &path,
|
||||
const std::string &options)
|
||||
|
@ -11324,42 +11441,6 @@ ircd::db::error_to_status::error_to_status(const std::error_code &e)
|
|||
{
|
||||
}
|
||||
|
||||
//
|
||||
// throw_on_error
|
||||
//
|
||||
|
||||
ircd::db::throw_on_error::throw_on_error(const rocksdb::Status &s)
|
||||
{
|
||||
using rocksdb::Status;
|
||||
|
||||
const string_view &message
|
||||
{
|
||||
s.getState()
|
||||
};
|
||||
|
||||
switch(s.code())
|
||||
{
|
||||
case Status::kOk: return;
|
||||
case Status::kNotFound: throw not_found{"%s", message};
|
||||
case Status::kCorruption: throw corruption{"%s", message};
|
||||
case Status::kNotSupported: throw not_supported{"%s", message};
|
||||
case Status::kInvalidArgument: throw invalid_argument{"%s", message};
|
||||
case Status::kIOError: throw io_error{"%s", message};
|
||||
case Status::kMergeInProgress: throw merge_in_progress{"%s", message};
|
||||
case Status::kIncomplete: throw incomplete{"%s", message};
|
||||
case Status::kShutdownInProgress: throw shutdown_in_progress{"%s", message};
|
||||
case Status::kTimedOut: throw timed_out{"%s", message};
|
||||
case Status::kAborted: throw aborted{"%s", message};
|
||||
case Status::kBusy: throw busy{"%s", message};
|
||||
case Status::kExpired: throw expired{"%s", message};
|
||||
case Status::kTryAgain: throw try_again{"%s", message};
|
||||
default: throw error
|
||||
{
|
||||
"code[%d] %s", s.code(), message
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
|
Loading…
Reference in a new issue