config/Path: throw std::runtime_error on error

This commit is contained in:
Max Kellermann 2016-11-07 09:07:50 +01:00
parent 4cd21f1e07
commit 4aab97ccb1
7 changed files with 42 additions and 68 deletions

View File

@ -24,7 +24,6 @@
#include "system/FatalError.hxx" #include "system/FatalError.hxx"
#include "fs/AllocatedPath.hxx" #include "fs/AllocatedPath.hxx"
#include "util/RuntimeError.hxx" #include "util/RuntimeError.hxx"
#include "util/Error.hxx"
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
@ -94,12 +93,10 @@ ConfigBlock::GetBlockValue(const char *name, const char *default_value) const
AllocatedPath AllocatedPath
ConfigBlock::GetPath(const char *name, const char *default_value) const ConfigBlock::GetPath(const char *name, const char *default_value) const
{ {
int line2 = line;
const char *s; const char *s;
const BlockParam *bp = GetBlockParam(name); const BlockParam *bp = GetBlockParam(name);
if (bp != nullptr) { if (bp != nullptr) {
line2 = bp->line;
s = bp->value.c_str(); s = bp->value.c_str();
} else { } else {
if (default_value == nullptr) if (default_value == nullptr)
@ -108,13 +105,7 @@ ConfigBlock::GetPath(const char *name, const char *default_value) const
s = default_value; s = default_value;
} }
Error error; return ParsePath(s);
AllocatedPath path = ParsePath(s, error);
if (gcc_unlikely(path.IsNull()))
throw FormatRuntimeError("Invalid path in \"%s\" at line %i: %s",
name, line2, error.GetMessage());
return path;
} }
int int

View File

@ -27,7 +27,6 @@
#include <string> #include <string>
#include <vector> #include <vector>
class Error;
class AllocatedPath; class AllocatedPath;
struct BlockParam { struct BlockParam {

View File

@ -23,7 +23,7 @@
#include "fs/Traits.hxx" #include "fs/Traits.hxx"
#include "fs/Domain.hxx" #include "fs/Domain.hxx"
#include "fs/StandardDirectory.hxx" #include "fs/StandardDirectory.hxx"
#include "util/Error.hxx" #include "util/RuntimeError.hxx"
#include "ConfigGlobal.hxx" #include "ConfigGlobal.hxx"
#include <assert.h> #include <assert.h>
@ -36,14 +36,11 @@
* Determine a given user's home directory. * Determine a given user's home directory.
*/ */
static AllocatedPath static AllocatedPath
GetHome(const char *user, Error &error) GetHome(const char *user)
{ {
AllocatedPath result = GetHomeDir(user); AllocatedPath result = GetHomeDir(user);
if (result.IsNull()) { if (result.IsNull())
error.Format(path_domain, throw FormatRuntimeError("no such user: %s", user);
"no such user: %s", user);
return AllocatedPath::Null();
}
return result; return result;
} }
@ -52,34 +49,33 @@ GetHome(const char *user, Error &error)
* Determine the current user's home directory. * Determine the current user's home directory.
*/ */
static AllocatedPath static AllocatedPath
GetHome(Error &error) GetHome()
{ {
AllocatedPath result = GetHomeDir(); AllocatedPath result = GetHomeDir();
if (result.IsNull()) { if (result.IsNull())
error.Set(path_domain, throw std::runtime_error("problems getting home for current user");
"problems getting home for current user");
return AllocatedPath::Null();
}
return result; return result;
} }
/** /**
* Determine the configured user's home directory. * Determine the configured user's home directory.
*
* Throws #std::runtime_error on error.
*/ */
static AllocatedPath static AllocatedPath
GetConfiguredHome(Error &error) GetConfiguredHome()
{ {
const char *user = config_get_string(ConfigOption::USER); const char *user = config_get_string(ConfigOption::USER);
return user != nullptr return user != nullptr
? GetHome(user, error) ? GetHome(user)
: GetHome(error); : GetHome();
} }
#endif #endif
AllocatedPath AllocatedPath
ParsePath(const char *path, Error &error) ParsePath(const char *path)
{ {
assert(path != nullptr); assert(path != nullptr);
@ -88,12 +84,12 @@ ParsePath(const char *path, Error &error)
++path; ++path;
if (*path == '\0') if (*path == '\0')
return GetConfiguredHome(error); return GetConfiguredHome();
AllocatedPath home = AllocatedPath::Null(); AllocatedPath home = AllocatedPath::Null();
if (*path == '/') { if (*path == '/') {
home = GetConfiguredHome(error); home = GetConfiguredHome();
++path; ++path;
} else { } else {
@ -102,7 +98,7 @@ ParsePath(const char *path, Error &error)
? path + strlen(path) ? path + strlen(path)
: slash; : slash;
const std::string user(path, end); const std::string user(path, end);
home = GetHome(user.c_str(), error); home = GetHome(user.c_str());
if (slash == nullptr) if (slash == nullptr)
return home; return home;
@ -113,18 +109,16 @@ ParsePath(const char *path, Error &error)
if (home.IsNull()) if (home.IsNull())
return AllocatedPath::Null(); return AllocatedPath::Null();
AllocatedPath path2 = AllocatedPath::FromUTF8(path, error); AllocatedPath path2 = AllocatedPath::FromUTF8Throw(path);
if (path2.IsNull()) if (path2.IsNull())
return AllocatedPath::Null(); return AllocatedPath::Null();
return AllocatedPath::Build(home, path2); return AllocatedPath::Build(home, path2);
} else if (!PathTraitsUTF8::IsAbsolute(path)) { } else if (!PathTraitsUTF8::IsAbsolute(path)) {
error.Format(path_domain, throw FormatRuntimeError("not an absolute path: %s", path);
"not an absolute path: %s", path);
return AllocatedPath::Null();
} else { } else {
#endif #endif
return AllocatedPath::FromUTF8(path, error); return AllocatedPath::FromUTF8Throw(path);
#ifndef WIN32 #ifndef WIN32
} }
#endif #endif

View File

@ -21,9 +21,11 @@
#define MPD_CONFIG_PATH_HXX #define MPD_CONFIG_PATH_HXX
class AllocatedPath; class AllocatedPath;
class Error;
/**
* Throws #std::runtime_error on error.
*/
AllocatedPath AllocatedPath
ParsePath(const char *path, Error &error); ParsePath(const char *path);
#endif #endif

View File

@ -21,7 +21,7 @@
#include "Param.hxx" #include "Param.hxx"
#include "ConfigPath.hxx" #include "ConfigPath.hxx"
#include "fs/AllocatedPath.hxx" #include "fs/AllocatedPath.hxx"
#include "util/Error.hxx" #include "util/RuntimeError.hxx"
#include <stdexcept> #include <stdexcept>
@ -33,25 +33,13 @@ ConfigParam::~ConfigParam()
delete next; delete next;
} }
AllocatedPath
ConfigParam::GetPath(Error &error) const
{
auto path = ParsePath(value.c_str(), error);
if (gcc_unlikely(path.IsNull()))
error.FormatPrefix("Invalid path at line %i: ", line);
return path;
}
AllocatedPath AllocatedPath
ConfigParam::GetPath() const ConfigParam::GetPath() const
{ {
Error error; try {
auto path = ParsePath(value.c_str(), error); return ParsePath(value.c_str());
if (gcc_unlikely(path.IsNull())) } catch (...) {
throw std::runtime_error(error.GetMessage()); std::throw_with_nested(FormatRuntimeError("Invalid path at line %i: ", line));
}
return path;
} }

View File

@ -66,13 +66,6 @@ struct ConfigParam {
return line < 0; return line < 0;
} }
/**
* Parse the value as a path. If there is a tilde prefix, it
* is expanded. If the path could not be parsed, returns
* AllocatedPath::Null() and sets the error.
*/
AllocatedPath GetPath(Error &error) const;
/** /**
* Parse the value as a path. If there is a tilde prefix, it * Parse the value as a path. If there is a tilde prefix, it
* is expanded. * is expanded.

View File

@ -33,6 +33,9 @@
#include "fs/io/FileOutputStream.hxx" #include "fs/io/FileOutputStream.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
#include "util/Domain.hxx" #include "util/Domain.hxx"
#include "util/ScopeExit.hxx"
#include <stdexcept>
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
@ -369,11 +372,14 @@ RecorderOutput::SendTag(const Tag &tag)
return; return;
} }
Error error; AtScopeExit(p) { free(p); };
AllocatedPath new_path = ParsePath(p, error);
free(p); AllocatedPath new_path = AllocatedPath::Null();
if (new_path.IsNull()) {
LogError(error); try {
new_path = ParsePath(p);
} catch (const std::runtime_error &e) {
LogError(e);
FinishFormat(); FinishFormat();
return; return;
} }
@ -381,6 +387,7 @@ RecorderOutput::SendTag(const Tag &tag)
if (new_path != path) { if (new_path != path) {
FinishFormat(); FinishFormat();
Error error;
if (!ReopenFormat(std::move(new_path), error)) { if (!ReopenFormat(std::move(new_path), error)) {
LogError(error); LogError(error);
return; return;