diff --git a/src/exception.h b/src/exception.h
new file mode 100644
index 0000000000000000000000000000000000000000..faf57bd4de33d2517907388f4eb1fb4813bee042
--- /dev/null
+++ b/src/exception.h
@@ -0,0 +1,34 @@
+#include <iostream>
+#include <stdexcept>
+#include <utility>
+
+#define THROW(ABC, msg) (throw ABC(msg, __FILE__, __LINE__));
+
+class RuntimeException : public std::runtime_error {
+ private:
+  const std::string fFileName;
+  std::size_t fLine;
+
+ public:
+  RuntimeException(const std::string &msg, std::string file, std::size_t ln) noexcept
+      : std::runtime_error(msg), fFileName(std::move(file)), fLine(ln) {}
+
+  virtual std::string GetMessage() const noexcept { return what(); }
+  virtual std::string GetFileName() const noexcept { return fFileName; }
+  virtual size_t GetLine() const noexcept { return fLine; }
+  ~RuntimeException() noexcept override = default;
+
+  virtual std::ostream &operator<<(std::ostream &out) const noexcept {
+    out << "Runtime exception: " << GetMessage() << std::endl;
+    out << " in " << GetFileName() << ":" << GetLine() << std::endl;
+    return out;
+  }
+};
+
+class FileException : public RuntimeException {
+  using RuntimeException::RuntimeException;
+};
+
+class ParseException : public RuntimeException {
+  using RuntimeException::RuntimeException;
+};
\ No newline at end of file