CommandError.cxx 2.8 KB
Newer Older
1
/*
Max Kellermann's avatar
Max Kellermann committed
2
 * Copyright 2003-2020 The Music Player Daemon Project
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
 * http://www.musicpd.org
 *
 * 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; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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.
 */

#include "config.h"
21
#include "CommandError.hxx"
22
#include "PlaylistError.hxx"
Max Kellermann's avatar
Max Kellermann committed
23
#include "db/DatabaseError.hxx"
24
#include "client/Response.hxx"
25
#include "Log.hxx"
26
#include "util/Exception.hxx"
27

28 29
#include <system_error>

30 31
gcc_const
static enum ack
32
ToAck(PlaylistResult result) noexcept
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
{
	switch (result) {
	case PlaylistResult::SUCCESS:
		break;

	case PlaylistResult::DENIED:
		return ACK_ERROR_PERMISSION;

	case PlaylistResult::NO_SUCH_SONG:
	case PlaylistResult::NO_SUCH_LIST:
		return ACK_ERROR_NO_EXIST;

	case PlaylistResult::LIST_EXISTS:
		return ACK_ERROR_EXIST;

	case PlaylistResult::BAD_NAME:
	case PlaylistResult::BAD_RANGE:
		return ACK_ERROR_ARG;

	case PlaylistResult::NOT_PLAYING:
		return ACK_ERROR_PLAYER_SYNC;

	case PlaylistResult::TOO_LARGE:
		return ACK_ERROR_PLAYLIST_MAX;

	case PlaylistResult::DISABLED:
		break;
	}

	return ACK_ERROR_UNKNOWN;
}

65 66 67
#ifdef ENABLE_DATABASE
gcc_const
static enum ack
68
ToAck(DatabaseErrorCode code) noexcept
69 70 71 72 73 74 75 76 77 78 79 80 81 82
{
	switch (code) {
	case DatabaseErrorCode::DISABLED:
	case DatabaseErrorCode::NOT_FOUND:
		return ACK_ERROR_NO_EXIST;

	case DatabaseErrorCode::CONFLICT:
		return ACK_ERROR_ARG;
	}

	return ACK_ERROR_UNKNOWN;
}
#endif

83 84
gcc_pure
static enum ack
85
ToAck(const std::exception_ptr& ep) noexcept
86 87 88 89 90 91 92
{
	try {
		std::rethrow_exception(ep);
	} catch (const ProtocolError &pe) {
		return pe.GetCode();
	} catch (const PlaylistError &pe) {
		return ToAck(pe.GetCode());
93 94 95 96
#ifdef ENABLE_DATABASE
	} catch (const DatabaseError &de) {
		return ToAck(de.GetCode());
#endif
97 98
	} catch (const std::system_error &e) {
		return ACK_ERROR_SYSTEM;
99 100
	} catch (const std::invalid_argument &e) {
		return ACK_ERROR_ARG;
101 102 103 104
	} catch (const std::length_error &e) {
		return ACK_ERROR_ARG;
	} catch (const std::out_of_range &e) {
		return ACK_ERROR_ARG;
105
	} catch (...) {
106 107 108 109 110 111
		try {
			std::rethrow_if_nested(ep);
			return ACK_ERROR_UNKNOWN;
		} catch (...) {
			return ToAck(std::current_exception());
		}
112 113 114
	}
}

115
void
116
PrintError(Response &r, const std::exception_ptr& ep)
117
{
118
	LogError(ep);
119
	r.Error(ToAck(ep), GetFullMessage(ep).c_str());
120
}