diff --git a/b_asic/port.py b/b_asic/port.py
index 7b750451c1262b1fd5196bc9308e86e7855271d4..f2a2532874b0fed1511c10633c36376805396240 100644
--- a/b_asic/port.py
+++ b/b_asic/port.py
@@ -172,9 +172,8 @@ class InputPort(AbstractPort):
         return [] if self._source_signal is None else [self._source_signal]
 
     def add_signal(self, signal: Signal) -> None:
-        assert (
-            self._source_signal is None
-        ), "Input port may have only one signal added."
+        if self._source_signal is not None:
+            raise ValueError("Cannot add to already connected input port.")
         assert (
             signal is not self._source_signal
         ), "Attempted to add already connected signal."
@@ -207,9 +206,8 @@ class InputPort(AbstractPort):
         Connect the provided signal source to this input port by creating a new signal.
         Returns the new signal.
         """
-        assert (
-            self._source_signal is None
-        ), "Attempted to connect already connected input port."
+        if self._source_signal is not None:
+            raise ValueError("Cannot connect already connected input port.")
         # self._source_signal is set by the signal constructor.
         return Signal(source=src.source, destination=self, name=name)
 
diff --git a/b_asic/scheduler_gui/main_window.py b/b_asic/scheduler_gui/main_window.py
index 6d834b0b308c921143339ac4bec6f1dfbb629988..7e3f1e2d289c9744db8db160339f439d965afba1 100644
--- a/b_asic/scheduler_gui/main_window.py
+++ b/b_asic/scheduler_gui/main_window.py
@@ -210,10 +210,10 @@ class MainWindow(QMainWindow, Ui_MainWindow):
             module = SourceFileLoader(
                 module_name, abs_path_filename
             ).load_module()
-        except:
+        except Exception as e:
             log.exception(
-                "Exception occurred. Could not load module from file '{}'."
-                .format(abs_path_filename)
+                "Exception occurred. Could not load module from file '{}'.\n\n{}"
+                .format(abs_path_filename, e)
             )
             return
 
diff --git a/b_asic/signal.py b/b_asic/signal.py
index 867f7ba78b14a2859c6ac9146a60914b52af46ee..63914c008d116def63287b5792d5292ca9b4f9bc 100644
--- a/b_asic/signal.py
+++ b/b_asic/signal.py
@@ -138,6 +138,10 @@ class Signal(AbstractGraphComponent):
         should truncate received values to.
         None = unlimited.
         """
-        if bits is not None and bits < 0:
-            raise ValueError("Bits cannot be negative")
+        if bits is not None:
+            if not isinstance(bits, int):
+                raise TypeError(
+                    f"Bits must be an int, not {type(bits)}: {bits!r}")
+            if bits < 0:
+                raise ValueError("Bits cannot be negative")
         self.set_param("bits", bits)
diff --git a/b_asic/signal_flow_graph.py b/b_asic/signal_flow_graph.py
index 8e87c71ab59c7eb2cfdce771e169676fbd72f6ce..37baeca884be6682d151ca708c99b544aa773fe0 100644
--- a/b_asic/signal_flow_graph.py
+++ b/b_asic/signal_flow_graph.py
@@ -624,12 +624,14 @@ class SFG(AbstractOperation):
         if output_comp is None:
             return None
 
-        assert not isinstance(
+        if isinstance(
             output_comp, Output
-        ), "Source operation can not be an output operation."
-        assert len(output_comp.output_signals) == component.input_count, (
-            "Source operation output count does not match input count for"
-            " component."
+        ):
+            raise TypeError("Source operation cannot be an output operation.")
+        if len(output_comp.output_signals) != component.input_count:
+            raise TypeError(
+            f"Source operation output count ({len(output_comp.output_signals)})"
+            f" does not match input count for component ({component.input_count})."
         )
         assert len(output_comp.output_signals) == component.output_count, (
             "Destination operation input count does not match output for"
diff --git a/test/test_inputport.py b/test/test_inputport.py
index 3d3e057c1ea033822e91d113db5692b13f4b1ab9..a94bbb7db415b66b30a3e9d0a8f4c790f6f720e6 100644
--- a/test/test_inputport.py
+++ b/test/test_inputport.py
@@ -27,7 +27,7 @@ def test_connect_then_disconnect(input_port, output_port):
 def test_connect_used_port_to_new_port(input_port, output_port, output_port2):
     """Multiple connections to an input port should throw an error."""
     input_port.connect(output_port)
-    with pytest.raises(Exception):
+    with pytest.raises(ValueError):
         input_port.connect(output_port2)
 
 
diff --git a/test/test_outputport.py b/test/test_outputport.py
index 8548cbbed19e1931584ba6762d4fe4da5e9017f6..3480c2ebc85c88a4cc58dd9b377d3d5863995ea2 100644
--- a/test/test_outputport.py
+++ b/test/test_outputport.py
@@ -17,7 +17,7 @@ class TestConnect:
     def test_same_port(self, output_port, input_port):
         """Check error handing."""
         input_port.connect(output_port)
-        with pytest.raises(Exception):
+        with pytest.raises(ValueError):
             input_port.connect(output_port)
 
         assert output_port.signal_count == 1
diff --git a/test/test_sfg.py b/test/test_sfg.py
index ac73cf3f5fa88e67c5ad0c7a69ee19f47dbcfe0e..300409959d9f74b6c49353431f113d1e00d0e46b 100644
--- a/test/test_sfg.py
+++ b/test/test_sfg.py
@@ -250,7 +250,7 @@ class TestEvaluateOutput:
 
     def test_evaluate_output_cycle(self, operation_graph_with_cycle):
         sfg = SFG(outputs=[Output(operation_graph_with_cycle)])
-        with pytest.raises(Exception):
+        with pytest.raises(RuntimeError, match="Direct feedback loop detected"):
             sfg.evaluate_output(0, [])
 
 
@@ -501,7 +501,7 @@ class TestInsertComponent:
 
         # Should raise an exception for not matching input count to output count.
         add4 = Addition()
-        with pytest.raises(Exception):
+        with pytest.raises(TypeError, match="Source operation output count"):
             sfg.insert_operation(add4, "c1")
 
     def test_insert_at_output(self, large_operation_tree):
@@ -509,7 +509,7 @@ class TestInsertComponent:
 
         # Should raise an exception for trying to insert an operation after an output.
         sqrt = SquareRoot()
-        with pytest.raises(Exception):
+        with pytest.raises(TypeError, match="Source operation cannot be an"):
             _ = sfg.insert_operation(sqrt, "out1")
 
     def test_insert_multiple_output_ports(self, butterfly_operation_tree):
@@ -1324,7 +1324,7 @@ class TestSaveLoadSFG:
 
     def test_load_invalid_path(self):
         path_ = self.get_path(existing=False)
-        with pytest.raises(Exception):
+        with pytest.raises(FileNotFoundError):
             python_to_sfg(path_)
 
 
diff --git a/test/test_signal.py b/test/test_signal.py
index 295cbb79476ee210f4de6e0dfc0b1c1e1cf08416..30186fd1df4e6757ca1ca61f0e538639e902a296 100644
--- a/test/test_signal.py
+++ b/test/test_signal.py
@@ -62,7 +62,7 @@ def test_signal_creation_and_disconnction_and_connection_changing():
     assert s.destination is in_port
 
 
-class Bits:
+class TestBits:
     def test_pos_int(self, signal):
         signal.bits = 10
         assert signal.bits == 10
@@ -72,15 +72,15 @@ class Bits:
         assert signal.bits == 0
 
     def test_bits_neg_int(self, signal):
-        with pytest.raises(Exception):
+        with pytest.raises(ValueError):
             signal.bits = -10
 
     def test_bits_complex(self, signal):
-        with pytest.raises(Exception):
+        with pytest.raises(TypeError):
             signal.bits = 2 + 4j
 
     def test_bits_float(self, signal):
-        with pytest.raises(Exception):
+        with pytest.raises(TypeError):
             signal.bits = 3.2
 
     def test_bits_pos_then_none(self, signal):