diff --git a/src/CSVReader/CSVReader.cpp b/src/CSVReader/CSVReader.cpp
index 11e82a0e868bb2c6751f1cbc29fe6840688c975f..61622786fd2a17e68a4e61afa7d4a6c9218ff556 100644
--- a/src/CSVReader/CSVReader.cpp
+++ b/src/CSVReader/CSVReader.cpp
@@ -6,13 +6,15 @@
 #include <fstream>
 #include <sstream>
 #include <filesystem>
+#include <regex>
 
 #include "CSVReader.h"
+#include "../exceptions.h"
 
 namespace lib4neuro {
     CSVReader::CSVReader(std::string file_path, std::string delimiter, bool ignore_first_line) {
         if(!std::filesystem::exists(file_path)) {
-            throw lib4neuro::FileNotFoundException("The specified file path in CSVReader does not exist!");
+            THROW_RUNTIME_ERROR("The specified file path in CSVReader does not exist!");
         }
 
         this->file_path = file_path;
@@ -74,9 +76,15 @@ namespace lib4neuro {
         std::vector<std::pair<std::vector<double>, std::vector<double>>> data_set_contents;
 
         for(auto line : *this->data) {
-            //TODO check for non-numerical (or empty) values in data
+            //TODO check empty values in data
             std::vector<double> input;
             for(auto ind : *input_col_indices) {
+                /* Check, if the string is a number */
+                if(!std::regex_match( line.at(ind), std::regex( ( "((\\+|-)?[[:digit:]]+)(\\.(([[:digit:]]+)?))?" ) ))) {
+                    THROW_RUNTIME_ERROR(std::string("Value \"") + line.at(ind) + "\" is not numerical and so it cannot be used in Data Set!");
+                }
+
+                /* Add loaded number to the vector of inputs */
                 input.push_back(std::stod(line.at(ind)));
             }
 
@@ -88,7 +96,6 @@ namespace lib4neuro {
             data_set_contents.emplace_back(std::make_pair(input, output));
         }
 
-//        DoubleUnitStrategy* ds = new DoubleUnitStrategy();
         return DataSet(&data_set_contents);
     }
 }
\ No newline at end of file
diff --git a/src/DataSet/DataSet.cpp b/src/DataSet/DataSet.cpp
index 72ce426af68e952da316cd3884ced66f47a268d6..cfb4c7ad1d3453dec3ed8908e2729afa7e3a7e47 100644
--- a/src/DataSet/DataSet.cpp
+++ b/src/DataSet/DataSet.cpp
@@ -6,6 +6,7 @@
 #include <boost/serialization/export.hpp>
 
 #include "DataSetSerialization.h"
+#include "../exceptions.h"
 
 BOOST_CLASS_EXPORT_IMPLEMENT(lib4neuro::DataSet);
 
@@ -24,7 +25,7 @@ namespace lib4neuro {
             ia >> *this;
             ifs.close();
         } else {
-            throw std::runtime_error("File couldn't be open!");
+            THROW_RUNTIME_ERROR("File couldn't be open!");
         }
 
     }
@@ -78,8 +79,6 @@ namespace lib4neuro {
 
         if(ns) {
             this->normalization_strategy = ns;
-//            this->max_min_inp_val.emplace_back(this->normalization_strategy->get_max_value());
-//            this->max_min_inp_val.emplace_back(this->normalization_strategy->get_min_value());
         }
 
         this->add_isotropic_data(bounds, no_elems_in_one_dim, output_func);
@@ -92,9 +91,9 @@ namespace lib4neuro {
         }
 
         if (inputs.size() != this->input_dim) {
-            throw InvalidDimension("Bad input dimension.");
+            THROW_RUNTIME_ERROR("Bad input dimension.");
         } else if (outputs.size() != this->output_dim) {
-            throw InvalidDimension("Bad output dimension.");
+            THROW_RUNTIME_ERROR("Bad output dimension.");
         }
 
         this->n_elements++;
@@ -104,8 +103,8 @@ namespace lib4neuro {
     void DataSet::add_isotropic_data(double lower_bound, double upper_bound, unsigned int size, double output) {
 
         if (this->input_dim != 1 || this->output_dim != 1) {
-            throw InvalidDimension("Cannot add data with dimensionality 1:1 when the data set "
-                                   "is of different dimensionality!");
+            THROW_RUNTIME_ERROR("Cannot add data with dimensionality 1:1 when the data set "
+                                "is of different dimensionality!");
         }
 
         double frac = (upper_bound - lower_bound) / (size - 1);
@@ -223,8 +222,8 @@ namespace lib4neuro {
 
     void DataSet::normalize() {
         if(!this->normalization_strategy) {
-            throw std::runtime_error("There is no normalization strategy given for this data set, so it can not be "
-                                     "normalized!");
+            THROW_INVALID_ARGUMENT_ERROR("There is no normalization strategy given for this data set, so it can not be "
+                                         "normalized!");
         }
 
         /* Find maximum and minimum values */
diff --git a/src/General/ExprtkWrapper.cpp b/src/General/ExprtkWrapper.cpp
index 3b3440bd66977ef023408157f4524ebe87c82ef5..81a73659a291d64b290b336e3b6b702ccfca0cb6 100644
--- a/src/General/ExprtkWrapper.cpp
+++ b/src/General/ExprtkWrapper.cpp
@@ -10,14 +10,14 @@
 #include "exprtk.hpp"
 #include "ExprtkWrapper.h"
 #include "ExprtkWrapperSerialization.h"
-#include "../Exception/Exceptions.h"
+#include "../../exceptions.h"
 
 BOOST_CLASS_EXPORT_IMPLEMENT(ExprtkWrapper);
 
 ExprtkWrapper::ExprtkWrapper() {
     // Because of serialization
     // TODO implement?
-    throw lib4neuro::NotImplementedException();
+    THROW_NOT_IMPLEMENTED_ERROR("This constructors is being used only for serialization purposes.");
 }
 
 ExprtkWrapper::ExprtkWrapper( std::string expression_string ) {
diff --git a/src/LearningMethods/ParticleSwarm.cpp b/src/LearningMethods/ParticleSwarm.cpp
index 5046f4e137646e0669cc65f8a99020e811f34ea8..a6a95c41c3d861ad810ccbdfa5924ba3dbd683c0 100644
--- a/src/LearningMethods/ParticleSwarm.cpp
+++ b/src/LearningMethods/ParticleSwarm.cpp
@@ -19,6 +19,7 @@
 #include "../message.h"
 #include "../Network/NeuralNetwork.h"
 #include "../DataSet/DataSet.h"
+#include "../exceptions.h"
 
 #include "ParticleSwarm.h"
 
@@ -204,7 +205,7 @@ namespace lib4neuro {
         srand(time(NULL));  //TODO rewrite using boost.random
 
         if (epsilon < 0 || gamma < 0 || delta < 0) {
-            throw std::invalid_argument(
+            THROW_INVALID_ARGUMENT_ERROR(
                     "Parameters 'gamma', 'epsilon' and 'delta' must be greater than or equal to zero!");
         }
 
@@ -264,7 +265,7 @@ namespace lib4neuro {
         }
 
         if (this->epsilon < 0 || this->gamma < 0 || this->delta < 0) {
-            throw std::invalid_argument(
+            THROW_INVALID_ARGUMENT_ERROR(
                     "Parameters 'gamma', 'epsilon' and 'delta' must be greater than or equal to zero!");
         }
 
diff --git a/src/NetConnection/ConnectionFunctionGeneral.cpp b/src/NetConnection/ConnectionFunctionGeneral.cpp
index 8174f5abfde4dd6ba32afa974fc50e573725dec9..9637f4f67f2217a4dfd5ee696ae9ce2cbd4ea0ed 100644
--- a/src/NetConnection/ConnectionFunctionGeneral.cpp
+++ b/src/NetConnection/ConnectionFunctionGeneral.cpp
@@ -8,6 +8,7 @@
 #include <boost/serialization/export.hpp>
 
 #include "ConnectionFunctionGeneralSerialization.h"
+#include "../exceptions.h"
 
 BOOST_CLASS_EXPORT_IMPLEMENT(ConnectionFunctionGeneral);
 
@@ -23,11 +24,11 @@ ConnectionFunctionGeneral::~ConnectionFunctionGeneral() {
 
 double ConnectionFunctionGeneral::eval( std::vector<double> &parameter_space ) {
     //TODO
-
+    THROW_NOT_IMPLEMENTED_ERROR();
     return 0.0;
 }
 
 void ConnectionFunctionGeneral::eval_partial_derivative(std::vector<double> &parameter_space, std::vector<double> &weight_gradient, double alpha) {
     //TODO
-    throw std::invalid_argument("Warning: ConnectionFunctionGeneral::eval_partial_derivative is not yet implemented\n");
+    THROW_NOT_IMPLEMENTED_ERROR();
 }
diff --git a/src/Network/NeuralNetwork.cpp b/src/Network/NeuralNetwork.cpp
index c4bca87522d44cf2cd0a31e9866ca3ba9c8596f4..ac4caafc4351128ae71361924e47f241311d28ba 100644
--- a/src/Network/NeuralNetwork.cpp
+++ b/src/Network/NeuralNetwork.cpp
@@ -11,6 +11,7 @@
 #include "../message.h"
 #include "NeuralNetwork.h"
 #include "NeuralNetworkSerialization.h"
+#include "../exceptions.h"
 
 
 namespace lib4neuro {
@@ -461,16 +462,16 @@ namespace lib4neuro {
     void NeuralNetwork::eval_single(std::vector<double> &input, ::std::vector<double> &output,
                                     ::std::vector<double> *custom_weights_and_biases) {
         if ((this->input_neuron_indices->size() * this->output_neuron_indices->size()) <= 0) {
-            throw std::invalid_argument("Input and output neurons have not been specified!");
+            THROW_INVALID_ARGUMENT_ERROR("Input and output neurons have not been specified!");
         }
 
 
         if (this->input_neuron_indices->size() != input.size()) {
-            throw std::invalid_argument("Error: input size != Network input size");
+            THROW_INVALID_ARGUMENT_ERROR("Error: input size != Network input size");
         }
 
         if (this->output_neuron_indices->size() != output.size()) {
-            throw std::invalid_argument("Error: output size != Network output size");
+            THROW_INVALID_ARGUMENT_ERROR("Error: output size != Network output size");
         }
         double potential, bias;
         int bias_idx;
@@ -584,7 +585,7 @@ namespace lib4neuro {
                         scaling_backprog[ti] += scaling_backprog[neuron_idx] * connection_weight;
                     }
                 } else {
-                    throw ::std::invalid_argument(
+                    THROW_INVALID_ARGUMENT_ERROR(
                             "Neuron used in backpropagation does not contain differentiable activation function!\n");
                 }
             }
@@ -894,15 +895,15 @@ namespace lib4neuro {
 
     void NeuralNetwork::set_normalization_strategy_instance(NormalizationStrategy *ns) {
         if(!ns) {
-            throw std::runtime_error("Argument 'ns' is not initialized!");
+            THROW_RUNTIME_ERROR("Argument 'ns' is not initialized!");
         }
         this->normalization_strategy = ns;
     }
 
     FullyConnectedFFN::FullyConnectedFFN(std::vector<unsigned int>* neuron_numbers, NEURON_TYPE hidden_layer_neuron_type) : NeuralNetwork() {
         if(neuron_numbers->size() < 2) {
-            throw std::invalid_argument("Parameter 'neuron_numbers' specifying numbers of neurons in network's layers "
-                                        "doesn't specify input and output layers, which are compulsory!");
+            THROW_INVALID_ARGUMENT_ERROR("Parameter 'neuron_numbers' specifying numbers of neurons in network's layers "
+                                         "doesn't specify input and output layers, which are compulsory!");
         }
 
         this->neurons = new ::std::vector<Neuron *>(0);
diff --git a/src/NormalizationStrategy/NormalizationStrategy.cpp b/src/NormalizationStrategy/NormalizationStrategy.cpp
index 32f475cac58d5323c93d34178f5d8a34f53c278e..432f800b9c4a81b3010ed1b6c54ade526342a18f 100644
--- a/src/NormalizationStrategy/NormalizationStrategy.cpp
+++ b/src/NormalizationStrategy/NormalizationStrategy.cpp
@@ -8,6 +8,7 @@
 
 #include "NormalizationStrategy.h"
 #include "NormalizationStrategySerialization.h"
+#include "../exceptions.h"
 
 BOOST_CLASS_EXPORT_IMPLEMENT(NormalizationStrategy);
 BOOST_CLASS_EXPORT_IMPLEMENT(DoubleUnitStrategy);
@@ -36,7 +37,7 @@ double DoubleUnitStrategy::normalize(double n, double max, double min) {
 
 double DoubleUnitStrategy::de_normalize(double n) {
     if(this->max_min_inp_val.empty()) {
-        throw std::runtime_error("Data were not normalized, so de-normalization cannot progress!");
+        THROW_RUNTIME_ERROR("Data were not normalized, so de-normalization cannot progress!");
     }
 
     return 0.5 * (1 + (this->get_max_value() - this->get_min_value()) * n) + this->get_min_value();
diff --git a/src/Solvers/DESolver.cpp b/src/Solvers/DESolver.cpp
index ef5e98fd6c2589ec8a22e1467c3618c2d75839c3..d284949a0a501e993a4845026cc06a772c283706 100644
--- a/src/Solvers/DESolver.cpp
+++ b/src/Solvers/DESolver.cpp
@@ -9,6 +9,7 @@
 
 #include "../message.h"
 #include "DESolver.h"
+#include "../exceptions.h"
 
 //TODO add support for multiple unknown functions
 
@@ -69,8 +70,7 @@ namespace lib4neuro {
     DESolver::DESolver(size_t n_equations, size_t n_inputs, size_t m) {
 
         if (m <= 0 || n_inputs <= 0 || n_equations <= 0) {
-            throw std::invalid_argument(
-                    "Parameters 'm', 'n_equations', 'n_inputs' and 'n_outputs' must be greater than zero!");
+            THROW_INVALID_ARGUMENT_ERROR("Parameters 'm', 'n_equations', 'n_inputs' and 'n_outputs' must be greater than zero!");
         }
         printf("Differential Equation Solver with %d equations\n--------------------------------------------------------------------------\n",
                (int) n_equations);
@@ -194,14 +194,13 @@ namespace lib4neuro {
     void DESolver::add_to_differential_equation(size_t equation_idx, MultiIndex &alpha, std::string expression_string) {
 
         if (equation_idx >= this->n_equations) {
-            throw std::invalid_argument("The provided equation index is too large!");
+            THROW_INVALID_ARGUMENT_ERROR("The provided equation index is too large!");
         }
 
         size_t derivative_degree = alpha.get_degree();
 
         if (derivative_degree > 2) {
-            throw std::invalid_argument(
-                    "The supplied multi-index represents partial derivative of order higher than 2! (Valid degree is at most 2)\n");
+            THROW_INVALID_ARGUMENT_ERROR("The supplied multi-index represents partial derivative of order higher than 2! (Valid degree is at most 2)\n");
         }
 
         /* retrieve indices of the variables according to which we perform the derivations ( applicable to any order, not just 2 or less )*/
@@ -354,8 +353,7 @@ namespace lib4neuro {
 
     void DESolver::set_error_function(size_t equation_idx, ErrorFunctionType F, DataSet *conditions) {
         if (equation_idx >= this->n_equations) {
-            throw std::invalid_argument(
-                    "The parameter 'equation_idx' is too large! It exceeds the number of differential equations.");
+            THROW_INVALID_ARGUMENT_ERROR("The parameter 'equation_idx' is too large! It exceeds the number of differential equations.");
         }
 
         this->errors_functions_types->at(equation_idx) = F;