Added error handling

This commit is contained in:
2025-08-29 00:02:45 +02:00
parent f93c463647
commit df4e7777de
17 changed files with 144 additions and 17 deletions

View File

@ -7,6 +7,7 @@
#include "lexer.hpp"
#include "util/text.hpp"
#include "util/error.hpp"
namespace fsh {
@ -67,9 +68,29 @@ namespace fsh {
private:
};
class AstBuildError : public std::runtime_error {
class AstBuildError : public util::LazyError {
public:
AstBuildError(std::string err) : std::runtime_error(err) {}
AstBuildError() {}
};
class AstUnexpectedTypeError : public AstBuildError {
public:
AstUnexpectedTypeError(Lexer::TokenType type) : type(type){};
private:
Lexer::TokenType type;
std::string build_msg() const noexcept override {
return (std::string) "Unexpected " + util::tokens[type];
};
};
class AstNoRedirectError : public AstBuildError {
private:
std::string build_msg() const noexcept override {
return "No redirects provided";
};
};
}

View File

@ -27,7 +27,7 @@ namespace fsh {
}
Command& get(const std::string n) {
if (cmds.find(n) == cmds.end()) { throw std::runtime_error("Command not found " + n); }
if (cmds.find(n) == cmds.end()) { throw util::CmdNotFoundError(n); }
return *(cmds[n]);
}

View File

@ -8,6 +8,7 @@
#include "ast/ast.hpp"
#include "cmd/args/arg.hpp"
#include "util/error.hpp"
namespace fsh {

View File

@ -17,7 +17,7 @@ namespace fsh {
virtual void run(std::istream& in, std::ostream& out, ArgManager& args) override {
if(std::remove(args.get<std::string>(0).value().c_str())) {
throw std::runtime_error("Could not delete file");
throw util::FileDeleteError();
}
}

View File

@ -15,7 +15,7 @@ namespace fsh {
virtual void run(std::istream& in, std::ostream& out, ArgManager& args) override {
auto name = *(args.get<std::string>(0));
if (std::ifstream(name, std::ios::in).good() || !std::ofstream(name, std::ios::out).is_open()) {
throw std::runtime_error("File exists");
throw util::FileExistsError();
}
}
};

View File

@ -33,7 +33,7 @@ namespace fsh {
protected:
std::string replace_all(std::string str,const std::string &what,const std::string &with) {
if(what == "") throw std::runtime_error("\"\" cannot be used as what");
if(what == "") throw util::CmdError("What cannot be empty string");
unsigned long long pos = str.find(what);

View File

@ -21,11 +21,11 @@ namespace fsh {
std::string filename = args.get<std::string>(0).value();
if(!std::ifstream(filename, std::ios_base::in)) {
throw std::runtime_error("File does not exist");
throw util::FileExistsError();
}
if(!std::ofstream(filename, std::ios_base::out)) {
throw std::runtime_error("Failed to truncate");
throw util::CmdError("Failed to truncate");
}
}

76
include/util/error.hpp Normal file
View File

@ -0,0 +1,76 @@
#pragma once
#include <stdexcept>
#include <optional>
namespace fsh::util {
// Generates msg only once what has been called
// Usefull for errors meant to be silently discarded frequently
class LazyError : public std::exception {
public:
LazyError() {}
LazyError(const std::string& msg_) : msg_(msg_) {}
LazyError(const char* msg_) : msg_(msg_) {}
const char* what() const noexcept override;
protected:
mutable std::optional<std::string> msg_;
virtual std::string build_msg() const noexcept;
};
class CmdNotFoundError : public LazyError {
public:
CmdNotFoundError(std::string cmd_) : cmd_(cmd_) {}
protected:
std::string build_msg() const noexcept override;
private:
std::string cmd_;
};
class CmdError : public LazyError {
public:
CmdError(const std::string& msg_) : LazyError(msg_) {}
CmdError(const char* msg_) : LazyError(msg_) {}
};
class RuntimeError : public std::exception {
public:
const char* msg_;
RuntimeError() = delete;
RuntimeError(const char* msg_) : msg_(msg_) {}
const char* what() const noexcept override;
};
class FileDeleteError : public RuntimeError {
public:
FileDeleteError() : RuntimeError("Error deleting file") {}
};
class FileExistsError : public RuntimeError {
public:
FileExistsError() : RuntimeError("File already exists") {}
};
class FileOpenError : public RuntimeError {
public:
FileOpenError() : RuntimeError("Failed to open file") {}
};
class DoubleInputError : public RuntimeError {
public:
DoubleInputError() : RuntimeError("Tried to set input twice") {}
};
class LexerError : public LazyError {
public:
LexerError(const std::string& msg_) : LazyError(msg_) {}
LexerError(const char* msg_) : LazyError(msg_) {}
};
}

View File

@ -4,6 +4,7 @@
#include <optional>
#include <fstream>
#include <stdexcept>
#include "error.hpp"
// Razlicite pomocne funkcije za tekstove
namespace fsh::util {
@ -25,19 +26,19 @@ namespace fsh::util {
static inline std::ifstream input(const std::string& x) {
std::ifstream in(x, std::ios::in);
if (!in) { throw std::runtime_error("Can't open file"); }
if (!in) { throw FileOpenError(); }
return in;
}
static inline std::ofstream output(const std::string& x) {
std::ofstream out(x, std::ios::out);
if (!out.is_open()) { throw std::runtime_error("Can't open file"); }
if (!out.is_open()) { throw FileOpenError(); }
return out;
}
static inline std::ofstream output_append(const std::string& x) {
std::ofstream out(x, std::ios::app | std::ios::out);
if (!out.is_open()) { throw std::runtime_error("Can't open file"); }
if (!out.is_open()) { throw FileOpenError(); }
return out;
}