diff --git a/file_backend.cpp b/file_backend.cpp index f3eea11..66aa6c9 100644 --- a/file_backend.cpp +++ b/file_backend.cpp @@ -14,7 +14,7 @@ void CFile::open(const char *fname) { name = fname; file = fopen(fname, "rb"); if (file == NULL) { - throw std::exception(); + throw NotFoundException(fname); } fseek(file, 0, SEEK_END); len = ftell(file); diff --git a/file_backend.hpp b/file_backend.hpp index 3c2cba8..ddba7ec 100644 --- a/file_backend.hpp +++ b/file_backend.hpp @@ -9,15 +9,54 @@ #include #include #include +#include +#include extern "C" { #include } #include "log.hpp" +#include +#include enum class SeekType { SET, CUR, END }; +class CustomException : public std::exception { + const char *message; + protected: + void clear_message(bool free_message = true) { + if (free_message && this->message != nullptr) { + free((void*)this->message); + } + this->message = nullptr; + } + public: + CustomException() { + clear_message(false); + } + CustomException(std::string message) : CustomException() { + set_message(message); + } + void set_message(std::string message) { + clear_message(); + this->message = strdup(message.c_str()); + } + const char *what() const throw() { + return this->message; + } + ~CustomException() { + clear_message(); + } +}; +class NotFoundException : public CustomException { + public: + NotFoundException(std::string file) : CustomException() { + set_message(fmt::format("File not found: {0}", file)); + } + NotFoundException(const char *file) : NotFoundException(std::string(file)) { } +}; + class File { protected: size_t len; diff --git a/playback.cpp b/playback.cpp index 61dd0e0..b6c35b7 100644 --- a/playback.cpp +++ b/playback.cpp @@ -137,9 +137,14 @@ void PlaybackInstance::Load(const char *file, int idx) { SDL_LockAudioDevice(device); playback_ready.store(false); if (process != nullptr) delete process; - process = new PlaybackProcess(file, idx); + try { + process = new PlaybackProcess(file, idx); + } catch (std::exception e) { + ERROR.writefln("Exception caught when creating process: %s", e.what()); + process = nullptr; + } length = 0.0; - if (process->process_running()) { + if (process != nullptr && process->process_running()) { length = process->get_length(); auto backend_spec_proxy = process->get_audio_spec(); memset(&backend_spec, 0, sizeof(backend_spec)); @@ -186,8 +191,7 @@ void PlaybackInstance::Load(const char *file, int idx) { load_finished.store(true); this->process->set_position(0.0); } else { - ERROR.writeln("Failed to detect valid playback backend for file!"); - set_error("Failed to detect valid backend for file."); + set_error("Failed to create playback backend."); set_signal(PlaybackSignalErrorOccurred); delete process; process = nullptr; @@ -387,7 +391,11 @@ void PlaybackInstance::LoopFunction() { } flag_mutex.unlock(); } - position = process->get_position(); + if (process) { + position = process->get_position(); + } else { + position = 0.0; + } } void PlaybackInstance::DeinitLoopFunction() { diff --git a/playback_process.cpp b/playback_process.cpp index b6348b9..387a1a4 100644 --- a/playback_process.cpp +++ b/playback_process.cpp @@ -291,6 +291,7 @@ ResetResponse PlaybackProcessServiceImpl::Reset(const ResetProperty *request) { return response; } MaybeError PlaybackProcessServiceImpl::Quit(const QuitCmd *request) { + if (process == nullptr) return MaybeError(); process->done = true; cur_backend_lock.get_unsafe()->cleanup(); return MaybeError(); @@ -302,6 +303,15 @@ MaybeError PlaybackProcessServiceImpl::Init(const InitCommand *cmd) { render_ptr.lock().set(new DynPtr(), true); lock.clear(); auto filename = cmd->filename(); + + if (!std::filesystem::exists(filename)) { + ErrorResponse *maybe_error = response->mutable_err(); + maybe_error->set_desc("File not found"); + maybe_error->set_id("not_found"); + maybe_error->set_fatal(true); + process->done = true; + return ret; + } auto idx = cmd->idx(); for (auto &backend : PlaybackBackendHelper()) { DEBUG.writefln("Trying backend: %s", backend.second->get_name().c_str()); @@ -317,11 +327,10 @@ MaybeError PlaybackProcessServiceImpl::Init(const InitCommand *cmd) { break; } if (!cur_backend_lock.has_value()) { - ErrorResponse *maybe_error = new ErrorResponse(); + ErrorResponse *maybe_error = response->mutable_err(); maybe_error->set_desc("Couldn't find a backend."); maybe_error->set_id("no_backend_for_file"); maybe_error->set_fatal(true); - response->set_allocated_err(maybe_error); process->done = true; DEBUG.writefln("Couldn't find any backend."); return ret; @@ -401,7 +410,11 @@ PlaybackProcess::PlaybackProcess(std::string filename, int idx) { call.mutable_init()->CopyFrom(cmd); RPCResponse response = SendCommand(&call); if (response.has_err()) { - throw std::exception(); + this->init_failed = true; + delete other_process; + other_process = nullptr; + auto err = response.err(); + throw CustomException(err.has_desc() ? err.desc() : err.id()); } } bool PlaybackProcess::process_running() { @@ -577,6 +590,10 @@ AudioSpec *PlaybackProcess::get_audio_spec() { return get_property_value(PropertyId::SpecProperty); } PlaybackProcess::~PlaybackProcess() { + if (init_failed || other_process == nullptr) { + done = true; + return; + } QuitCmd quit_cmd; RPCCall call; call.mutable_quit()->CopyFrom(quit_cmd); diff --git a/playback_process.hpp b/playback_process.hpp index 8539f11..4d3aeaf 100644 --- a/playback_process.hpp +++ b/playback_process.hpp @@ -45,6 +45,7 @@ class PlaybackProcess { PlaybackProcess *other_process = nullptr; PlaybackProcessServiceImpl impl; int pid; + bool init_failed = false; std::mutex start_mutex; std::condition_variable started; bool is_playback_process = false; diff --git a/util.hpp b/util.hpp index 9577928..8aa03e4 100644 --- a/util.hpp +++ b/util.hpp @@ -345,4 +345,4 @@ class DynPtr { return get_byte_sized(len * sizeof(T)); } } -}; \ No newline at end of file +};