From dab55bf8f2abc545debf8c968f235636611edc40 Mon Sep 17 00:00:00 2001
From: Vetle <vetletb@stud.ntnu.no>
Date: Thu, 16 May 2024 13:15:15 +0200
Subject: [PATCH 1/3] Remade custom exceptions to reflex what went wrong, not
 where

---
 .../exceptions/ChaosCanvasException.java      | 32 ------------------
 .../ChaosGameDescriptionException.java        | 32 ------------------
 .../ChaosGameDescriptionFactoryException.java | 32 ------------------
 .../exceptions/ChaosGameException.java        | 32 ------------------
 .../ChaosGameFileHandlerException.java        | 32 ------------------
 .../exceptions/CouldNotWriteException.java    | 32 ++++++++++++++++++
 .../exceptions/EmptyListException.java        | 32 ++++++++++++++++++
 .../InvalidPositiveIntException.java          | 32 ++++++++++++++++++
 .../exceptions/InvalidSignException.java      | 33 +++++++++++++++++++
 .../exceptions/InvalidTypeException.java      | 32 ++++++++++++++++++
 .../InvalidVectorRangeException.java          | 33 +++++++++++++++++++
 .../idatt2003/exceptions/IsNullException.java | 32 ++++++++++++++++++
 .../exceptions/ObservingException.java        | 32 ++++++++++++++++++
 .../exceptions/WrongLengthException.java      | 32 ++++++++++++++++++
 14 files changed, 290 insertions(+), 160 deletions(-)
 delete mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/ChaosCanvasException.java
 delete mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameDescriptionException.java
 delete mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameDescriptionFactoryException.java
 delete mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameException.java
 delete mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameFileHandlerException.java
 create mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/CouldNotWriteException.java
 create mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/EmptyListException.java
 create mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/InvalidPositiveIntException.java
 create mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/InvalidSignException.java
 create mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/InvalidTypeException.java
 create mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/InvalidVectorRangeException.java
 create mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/IsNullException.java
 create mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/ObservingException.java
 create mode 100644 src/main/java/edu/ntnu/idatt2003/exceptions/WrongLengthException.java

diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosCanvasException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosCanvasException.java
deleted file mode 100644
index 4e0cde2..0000000
--- a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosCanvasException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package edu.ntnu.idatt2003.exceptions;
-
-/**
- * Exception class for ChaosCanvas.
- */
-public class ChaosCanvasException extends Exception {
-  /**
-   * Constructs a new ChaosCanvasException with the default message.
-   */
-  public ChaosCanvasException() {
-    super("Chaos canvas exception occurred.");
-  }
-
-  /**
-   * Constructs a new ChaosCanvasException with the specified message and cause.
-   *
-   * @param message the message
-   * @param cause the cause
-   */
-  public ChaosCanvasException(String message, Throwable cause) {
-    super(message, cause);
-  }
-
-  /**
-   * Constructs a new ChaosCanvasException with the specified message.
-   *
-   * @param message the message
-   */
-  public ChaosCanvasException(String message) {
-    super(message);
-  }
-}
diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameDescriptionException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameDescriptionException.java
deleted file mode 100644
index 679b88d..0000000
--- a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameDescriptionException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package edu.ntnu.idatt2003.exceptions;
-
-/**
- * Exception class for ChaosGameDescription.
- */
-public class ChaosGameDescriptionException extends Exception {
-  /**
-   * Constructs a new ChaosGameDescriptionException with the default message.
-   */
-  public ChaosGameDescriptionException() {
-    super("An error occurred in the ChaosGameDescription class.");
-  }
-
-  /**
-   * Constructs a new ChaosGameDescriptionException with the specified message.
-   *
-   * @param message the message
-   */
-  public ChaosGameDescriptionException(String message) {
-    super(message);
-  }
-
-  /**
-   * Constructs a new ChaosGameDescriptionException with the specified message and cause.
-   *
-   * @param message the message
-   * @param cause the cause
-   */
-  public ChaosGameDescriptionException(String message, Throwable cause) {
-    super(message, cause);
-  }
-}
diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameDescriptionFactoryException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameDescriptionFactoryException.java
deleted file mode 100644
index 9d9acce..0000000
--- a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameDescriptionFactoryException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package edu.ntnu.idatt2003.exceptions;
-
-/**
- * Exception class for ChaosGameDescriptionFactory.
- */
-public class ChaosGameDescriptionFactoryException extends Exception {
-  /**
-   * Constructs a new ChaosGameDescriptionFactoryException with the default message.
-   */
-  public ChaosGameDescriptionFactoryException() {
-    super("An error occurred while creating a ChaosGameDescription object.");
-  }
-
-  /**
-   * Constructs a new ChaosGameDescriptionFactoryException with the specified message and cause.
-   *
-   * @param message the message
-   * @param cause the cause
-   */
-  public ChaosGameDescriptionFactoryException(String message, Throwable cause) {
-    super(message, cause);
-  }
-
-  /**
-   * Constructs a new ChaosGameDescriptionFactoryException with the specified message.
-   *
-   * @param message the message
-   */
-  public ChaosGameDescriptionFactoryException(String message) {
-    super(message);
-  }
-}
diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameException.java
deleted file mode 100644
index e31a7ea..0000000
--- a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package edu.ntnu.idatt2003.exceptions;
-
-/**
- * Exception class for ChaosGame.
- */
-public class ChaosGameException extends Exception {
-  /**
-   * Constructs a new ChaosGameException with the default message.
-   */
-  public ChaosGameException() {
-    super("Chaos game exception occurred.");
-  }
-
-  /**
-   * Constructs a new ChaosGameException with the specified message and cause.
-   *
-   * @param message the message
-   * @param cause the cause
-   */
-  public ChaosGameException(String message, Throwable cause) {
-    super(message, cause);
-  }
-
-  /**
-   * Constructs a new ChaosGameException with the specified message.
-   *
-   * @param message the message
-   */
-  public ChaosGameException(String message) {
-    super(message);
-  }
-}
diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameFileHandlerException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameFileHandlerException.java
deleted file mode 100644
index 1f6c62e..0000000
--- a/src/main/java/edu/ntnu/idatt2003/exceptions/ChaosGameFileHandlerException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package edu.ntnu.idatt2003.exceptions;
-
-/**
- * Exception class for ChaosGameFileHandler.
- */
-public class ChaosGameFileHandlerException extends Exception {
-  /**
-   * Constructs a new ChaosGameFileHandlerException with the default message.
-   */
-  public ChaosGameFileHandlerException() {
-    super("An error occurred while handling the file");
-  }
-
-  /**
-   * Constructs a new ChaosGameFileHandlerException with the specified message and cause.
-   *
-   * @param message the message
-   * @param cause the cause
-   */
-  public ChaosGameFileHandlerException(String message, Throwable cause) {
-    super(message, cause);
-  }
-
-  /**
-   * Constructs a new ChaosGameFileHandlerException with the specified message.
-   *
-   * @param message the message
-   */
-  public ChaosGameFileHandlerException(String message) {
-    super(message);
-  }
-}
diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/CouldNotWriteException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/CouldNotWriteException.java
new file mode 100644
index 0000000..6617c12
--- /dev/null
+++ b/src/main/java/edu/ntnu/idatt2003/exceptions/CouldNotWriteException.java
@@ -0,0 +1,32 @@
+package edu.ntnu.idatt2003.exceptions;
+
+/**
+ * Exception class for when a file could not be written to.
+ */
+public class CouldNotWriteException extends Exception {
+  /**
+   * Constructs a new CouldNotWriteException with the default message.
+   */
+  public CouldNotWriteException() {
+    super("Could not write exception occurred.");
+  }
+
+  /**
+   * Constructs a new CouldNotWriteException with the specified message and cause.
+   *
+   * @param message the message
+   * @param cause the cause
+   */
+  public CouldNotWriteException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  /**
+   * Constructs a new CouldNotWriteException with the specified message.
+   *
+   * @param message the message
+   */
+  public CouldNotWriteException(String message) {
+    super(message);
+  }
+}
diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/EmptyListException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/EmptyListException.java
new file mode 100644
index 0000000..9e3e27b
--- /dev/null
+++ b/src/main/java/edu/ntnu/idatt2003/exceptions/EmptyListException.java
@@ -0,0 +1,32 @@
+package edu.ntnu.idatt2003.exceptions;
+
+/**
+ * Exception class for empty lists.
+ */
+public class EmptyListException extends Exception {
+  /**
+   * Constructs a new EmptyListException with the default message.
+   */
+  public EmptyListException() {
+    super("Empty list exception occurred.");
+  }
+
+  /**
+   * Constructs a new EmptyListException with the specified message and cause.
+   *
+   * @param message the message
+   * @param cause the cause
+   */
+  public EmptyListException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  /**
+   * Constructs a new EmptyListException with the specified message.
+   *
+   * @param message the message
+   */
+  public EmptyListException(String message) {
+    super(message);
+  }
+}
diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidPositiveIntException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidPositiveIntException.java
new file mode 100644
index 0000000..ecd5d1b
--- /dev/null
+++ b/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidPositiveIntException.java
@@ -0,0 +1,32 @@
+package edu.ntnu.idatt2003.exceptions;
+
+/**
+ * Exception class for invalid positive integers.
+ */
+public class InvalidPositiveIntException extends Exception {
+  /**
+   * Constructs a new InvalidPositiveIntException with the default message.
+   */
+  public InvalidPositiveIntException() {
+    super("Invalid positive integer exception occurred.");
+  }
+
+  /**
+   * Constructs a new InvalidPositiveIntException with the specified message and cause.
+   *
+   * @param message the message
+   * @param cause   the cause
+   */
+  public InvalidPositiveIntException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  /**
+   * Constructs a new InvalidPositiveIntException with the specified message.
+   *
+   * @param message the message
+   */
+  public InvalidPositiveIntException(String message) {
+    super(message);
+  }
+}
\ No newline at end of file
diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidSignException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidSignException.java
new file mode 100644
index 0000000..8f1e11f
--- /dev/null
+++ b/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidSignException.java
@@ -0,0 +1,33 @@
+package edu.ntnu.idatt2003.exceptions;
+
+/**
+ * Exception class for invalid signs.
+ */
+public class InvalidSignException extends Exception {
+
+  /**
+   * Constructs a new InvalidSignException with the default message.
+   */
+  public InvalidSignException() {
+    super("Invalid sign exception occurred.");
+  }
+
+  /**
+   * Constructs a new InvalidSignException with the specified message and cause.
+   *
+   * @param message the message
+   * @param cause the cause
+   */
+  public InvalidSignException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  /**
+   * Constructs a new InvalidSignException with the specified message.
+   *
+   * @param message the message
+   */
+  public InvalidSignException(String message) {
+    super(message);
+  }
+}
diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidTypeException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidTypeException.java
new file mode 100644
index 0000000..37d2f80
--- /dev/null
+++ b/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidTypeException.java
@@ -0,0 +1,32 @@
+package edu.ntnu.idatt2003.exceptions;
+
+/**
+ * Exception class for invalid types.
+ */
+public class InvalidTypeException extends Exception {
+  /**
+   * Constructs a new InvalidTypeException with the default message.
+   */
+  public InvalidTypeException() {
+    super("Invalid type exception occurred.");
+  }
+
+  /**
+   * Constructs a new InvalidTypeException with the specified message and cause.
+   *
+   * @param message the message
+   * @param cause   the cause
+   */
+  public InvalidTypeException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  /**
+   * Constructs a new InvalidTypeException with the specified message.
+   *
+   * @param message the message
+   */
+  public InvalidTypeException(String message) {
+    super(message);
+  }
+}
diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidVectorRangeException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidVectorRangeException.java
new file mode 100644
index 0000000..38d5b2f
--- /dev/null
+++ b/src/main/java/edu/ntnu/idatt2003/exceptions/InvalidVectorRangeException.java
@@ -0,0 +1,33 @@
+package edu.ntnu.idatt2003.exceptions;
+
+/**
+ * Exception class for invalid vector ranges.
+ */
+public class InvalidVectorRangeException extends Exception {
+
+  /**
+   * Constructs a new InvalidVectorRangeException with the default message.
+   */
+  public InvalidVectorRangeException() {
+    super("Invalid vector range exception occurred.");
+  }
+
+  /**
+   * Constructs a new InvalidVectorRangeException with the specified message and cause.
+   *
+   * @param message the message
+   * @param cause   the cause
+   */
+  public InvalidVectorRangeException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  /**
+   * Constructs a new InvalidVectorRangeException with the specified message.
+   *
+   * @param message the message
+   */
+  public InvalidVectorRangeException(String message) {
+    super(message);
+  }
+}
diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/IsNullException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/IsNullException.java
new file mode 100644
index 0000000..3e4483c
--- /dev/null
+++ b/src/main/java/edu/ntnu/idatt2003/exceptions/IsNullException.java
@@ -0,0 +1,32 @@
+package edu.ntnu.idatt2003.exceptions;
+
+/**
+ * Exception class for objects that are null.
+ */
+public class IsNullException extends Exception {
+  /**
+   * Constructs a new NullException with the default message.
+   */
+  public IsNullException() {
+    super("Null exception occurred.");
+  }
+
+  /**
+   * Constructs a new NullException with the specified message and cause.
+   *
+   * @param message the message
+   * @param cause the cause
+   */
+  public IsNullException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  /**
+   * Constructs a new NullException with the specified message.
+   *
+   * @param message the message
+   */
+  public IsNullException(String message) {
+    super(message);
+  }
+}
diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/ObservingException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/ObservingException.java
new file mode 100644
index 0000000..5139a67
--- /dev/null
+++ b/src/main/java/edu/ntnu/idatt2003/exceptions/ObservingException.java
@@ -0,0 +1,32 @@
+package edu.ntnu.idatt2003.exceptions;
+
+/**
+ * Exception class for exceptions caused by observing.
+ */
+public class ObservingException extends Exception {
+  /**
+   * Constructs a new ObservingException with the default message.
+   */
+  public ObservingException() {
+    super("Observing exception occurred.");
+  }
+
+  /**
+   * Constructs a new ObservingException with the specified message and cause.
+   *
+   * @param message the message
+   * @param cause the cause
+   */
+  public ObservingException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  /**
+   * Constructs a new ObservingException with the specified message.
+   *
+   * @param message the message
+   */
+  public ObservingException(String message) {
+    super(message);
+  }
+}
diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/WrongLengthException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/WrongLengthException.java
new file mode 100644
index 0000000..5d3cd25
--- /dev/null
+++ b/src/main/java/edu/ntnu/idatt2003/exceptions/WrongLengthException.java
@@ -0,0 +1,32 @@
+package edu.ntnu.idatt2003.exceptions;
+
+/**
+ * Exception class for wrong length.
+ */
+public class WrongLengthException extends Exception {
+  /**
+   * Constructs a new WrongLengthException with the default message.
+   */
+  public WrongLengthException() {
+    super("Wrong length exception occurred.");
+  }
+
+  /**
+   * Constructs a new WrongLengthException with the specified message and cause.
+   *
+   * @param message the message
+   * @param cause the cause
+   */
+  public WrongLengthException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  /**
+   * Constructs a new WrongLengthException with the specified message.
+   *
+   * @param message the message
+   */
+  public WrongLengthException(String message) {
+    super(message);
+  }
+}
-- 
GitLab


From 28b1aa2bda75b1cc68f39ced980052750fd8ffab Mon Sep 17 00:00:00 2001
From: Vetle <vetletb@stud.ntnu.no>
Date: Thu, 16 May 2024 13:15:58 +0200
Subject: [PATCH 2/3] Implemented new exceptions

---
 .../exceptions/WrongFileFormatException.java  |   4 +-
 .../idatt2003/model/game/ChaosCanvas.java     |  55 +++++----
 .../ntnu/idatt2003/model/game/ChaosGame.java  |  60 +++++-----
 .../model/game/ChaosGameDescription.java      |  36 +++---
 .../game/ChaosGameDescriptionFactory.java     |  71 ++++++-----
 .../model/io/ChaosGameFileHandler.java        | 112 +++++++++++-------
 .../math/transformation/JuliaTransform.java   |   7 +-
 .../ntnu/idatt2003/util/InputValidation.java  |  71 +++++++++--
 .../idatt2003/model/game/ChaosCanvasTest.java |  27 +++--
 .../game/ChaosGameDescriptionFactoryTest.java |  19 ++-
 .../model/game/ChaosGameDescriptionTest.java  |  36 +++---
 .../idatt2003/model/game/ChaosGameTest.java   |  52 ++++----
 .../model/io/ChaosGameFileHandlerTest.java    |  24 ++--
 .../transformation/JuliaTransformTest.java    |  21 ++--
 14 files changed, 362 insertions(+), 233 deletions(-)

diff --git a/src/main/java/edu/ntnu/idatt2003/exceptions/WrongFileFormatException.java b/src/main/java/edu/ntnu/idatt2003/exceptions/WrongFileFormatException.java
index d558923..d934051 100644
--- a/src/main/java/edu/ntnu/idatt2003/exceptions/WrongFileFormatException.java
+++ b/src/main/java/edu/ntnu/idatt2003/exceptions/WrongFileFormatException.java
@@ -1,9 +1,9 @@
 package edu.ntnu.idatt2003.exceptions;
 
 /**
- * Exception class for ChaosGameFileHandler.
+ * Exception class for wrongly formatted files.
  */
-public class WrongFileFormatException extends ChaosGameFileHandlerException {
+public class WrongFileFormatException extends Exception {
   /**
    * Constructs a new WrongFileFormatException with the default message.
    */
diff --git a/src/main/java/edu/ntnu/idatt2003/model/game/ChaosCanvas.java b/src/main/java/edu/ntnu/idatt2003/model/game/ChaosCanvas.java
index 73c0ac5..0be394a 100644
--- a/src/main/java/edu/ntnu/idatt2003/model/game/ChaosCanvas.java
+++ b/src/main/java/edu/ntnu/idatt2003/model/game/ChaosCanvas.java
@@ -1,6 +1,8 @@
 package edu.ntnu.idatt2003.model.game;
 
-import edu.ntnu.idatt2003.exceptions.ChaosCanvasException;
+import edu.ntnu.idatt2003.exceptions.InvalidPositiveIntException;
+import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException;
+import edu.ntnu.idatt2003.exceptions.IsNullException;
 import edu.ntnu.idatt2003.model.math.mathModel.Matrix2x2;
 import edu.ntnu.idatt2003.model.math.mathModel.Vector2D;
 import edu.ntnu.idatt2003.model.math.transformation.AffineTransform2D;
@@ -28,20 +30,20 @@ public class ChaosCanvas {
    * @param minCoords the minimum coordinates of the canvas.
    * @param maxCoords the maximum coordinates of the canvas.
    *
-   * @throws IllegalArgumentException if width is not positive,
-   *                                  if height is not positive,
-   *                                  if minCoords is null,
-   *                                  if maxCoords is null
+   * @throws InvalidPositiveIntException if width is not positive,
+   *      if height is not positive,
+   *      if minCoords is null,
+   *      if maxCoords is null
+   * @throws IsNullException if minCoords or maxCoords are null,
+   * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the
+   *     maximum coordinates.
    */
   public ChaosCanvas(int width, int height, Vector2D minCoords, Vector2D maxCoords)
-      throws ChaosCanvasException {
-    try {
-      InputValidation.validatePositiveInt(width, "width");
-      InputValidation.validatePositiveInt(height, "height");
-      setMinMaxCoords(minCoords, maxCoords);
-    } catch (IllegalArgumentException e) {
-      throw new ChaosCanvasException("An error occurred while creating the ChaosCanvas class", e);
-    }
+      throws InvalidPositiveIntException, IsNullException, InvalidVectorRangeException {
+    InputValidation.validatePositiveInt(width, "width");
+    InputValidation.validatePositiveInt(height, "height");
+
+    setMinMaxCoords(minCoords, maxCoords);
     this.width = width;
     this.height = height;
     this.canvas = new int[width][height];
@@ -69,8 +71,9 @@ public class ChaosCanvas {
    * Sets the minimum coordinates of the canvas.
    *
    * @param minCoords the minimum coordinates of the canvas.
+   * @throws IsNullException if minCoords is null
    */
-  private void setMinCoords(Vector2D minCoords) {
+  private void setMinCoords(Vector2D minCoords) throws IsNullException {
     InputValidation.validateNotNull(minCoords, "minCoords");
     this.minCoords = minCoords;
   }
@@ -79,8 +82,9 @@ public class ChaosCanvas {
    * Sets the maximum coordinates of the canvas.
    *
    * @param maxCoords the maximum coordinates of the canvas.
+   * @throws IsNullException if maxCoords is null
    */
-  private void setMaxCoords(Vector2D maxCoords) {
+  private void setMaxCoords(Vector2D maxCoords) throws IsNullException {
     InputValidation.validateNotNull(maxCoords, "maxCoords");
     this.maxCoords = maxCoords;
   }
@@ -91,18 +95,17 @@ public class ChaosCanvas {
    * @param minCoords the minimum coordinates of the canvas.
    * @param maxCoords the maximum coordinates of the canvas.
    *
-   * @throws IllegalArgumentException if minCoords is null,
-   *                                  if maxCoords is null
+   * @throws IsNullException if minCoords is null,
+   *      if maxCoords is null
    */
-  public void setMinMaxCoords(Vector2D minCoords, Vector2D maxCoords) throws ChaosCanvasException {
-    try {
-      setMinCoords(minCoords);
-      setMaxCoords(maxCoords);
-      setTransformCoordsToIndices();
-    } catch (IllegalArgumentException e) {
-      throw new ChaosCanvasException(
-          "An error occurred while setting the min and max coordinates", e);
-    }
+  public void setMinMaxCoords(Vector2D minCoords, Vector2D maxCoords)
+      throws IsNullException, InvalidVectorRangeException {
+    setMinCoords(minCoords);
+    setMaxCoords(maxCoords);
+
+    InputValidation.validateVectorRange(minCoords, maxCoords);
+
+    setTransformCoordsToIndices();
   }
 
   /**
diff --git a/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGame.java b/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGame.java
index c101d84..07ae75f 100644
--- a/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGame.java
+++ b/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGame.java
@@ -1,7 +1,8 @@
 package edu.ntnu.idatt2003.model.game;
 
-import edu.ntnu.idatt2003.exceptions.ChaosCanvasException;
-import edu.ntnu.idatt2003.exceptions.ChaosGameException;
+import edu.ntnu.idatt2003.exceptions.InvalidPositiveIntException;
+import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException;
+import edu.ntnu.idatt2003.exceptions.IsNullException;
 import edu.ntnu.idatt2003.model.math.mathModel.Vector2D;
 import edu.ntnu.idatt2003.model.math.transformation.Transform2D;
 import edu.ntnu.idatt2003.util.InputValidation;
@@ -23,18 +24,18 @@ public class ChaosGame extends Subject {
    * @param description the description of the chaos game.
    * @param width the width of the canvas.
    * @param height the height of the canvas.
+   * @throws IsNullException if the description is null.
+   * @throws InvalidPositiveIntException if the width or height are not positive.
+   * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the
+   *      maximum coordinates.
    */
   public ChaosGame(ChaosGameDescription description, int width, int height)
-      throws ChaosGameException {
-    try {
-      InputValidation.validateNotNull(description, "description");
-      this.canvas = new ChaosCanvas(
-          width, height, description.getMinCoords(), description.getMaxCoords());
-    } catch (IllegalArgumentException e) {
-      throw new ChaosGameException("The description of the chaos game cannot be null.", e);
-    } catch (ChaosCanvasException e) {
-      throw new ChaosGameException("An error occurred while creating the ChaosCanvas class.", e);
-    }
+      throws IsNullException, InvalidPositiveIntException,
+      InvalidVectorRangeException {
+    InputValidation.validateNotNull(description, "description");
+
+    this.canvas = new ChaosCanvas(
+        width, height, description.getMinCoords(), description.getMaxCoords());
     this.description = description;
     this.currentPoint = new Vector2D(0, 0);
     this.random = new Random();
@@ -60,17 +61,17 @@ public class ChaosGame extends Subject {
 
   /**
    * Sets the description of the chaos game.
+   *
+   * @param description the description of the chaos game.
+   * @throws IsNullException if the description is null.
+   * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the
+   *     maximum coordinates.
    */
-  private void setDescription(ChaosGameDescription description) throws ChaosGameException {
-    try {
-      InputValidation.validateNotNull(description, "description");
-      canvas.setMinMaxCoords(description.getMinCoords(), description.getMaxCoords());
-    } catch (IllegalArgumentException e) {
-      throw new ChaosGameException("The description of the chaos game cannot be null.", e);
-    } catch (ChaosCanvasException e) {
-      throw new ChaosGameException(
-          "An error occurred while setting the description of the chaos game.", e);
-    }
+  private void setDescription(ChaosGameDescription description)
+      throws IsNullException, InvalidVectorRangeException {
+    InputValidation.validateNotNull(description, "description");
+
+    canvas.setMinMaxCoords(description.getMinCoords(), description.getMaxCoords());
     this.description = description;
     notifyObservers("setDescription");
   }
@@ -88,8 +89,11 @@ public class ChaosGame extends Subject {
    * Resets the canvas and sets new description for the chaos game.
    *
    * @param description the description to reset the chaos game with.
+   * @throws IsNullException if the description is null.
+   * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the
    */
-  public void resetGameWithDescription(ChaosGameDescription description) throws ChaosGameException {
+  public void resetGameWithDescription(ChaosGameDescription description)
+      throws IsNullException, InvalidVectorRangeException {
     setDescription(description);
     resetGame();
   }
@@ -98,13 +102,11 @@ public class ChaosGame extends Subject {
    * Runs the chaos game for the given number of steps.
    *
    * @param steps the number of steps to run the chaos game for.
+   * @throws InvalidPositiveIntException if the number of steps is not positive.
    */
-  public void runSteps(int steps) throws ChaosGameException {
-    try {
-      InputValidation.validatePositiveInt(steps, "steps");
-    } catch (IllegalArgumentException e) {
-      throw new ChaosGameException("The number of steps must be positive.", e);
-    }
+  public void runSteps(int steps) throws InvalidPositiveIntException {
+    InputValidation.validatePositiveInt(steps, "steps");
+
     List<Transform2D> transforms = description.getTransforms();
     for (int i = 0; i < steps; i++) {
       Transform2D currentTransformation = transforms.get(random.nextInt(transforms.size()));
diff --git a/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGameDescription.java b/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGameDescription.java
index 8488aa7..fa61df3 100644
--- a/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGameDescription.java
+++ b/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGameDescription.java
@@ -1,6 +1,8 @@
 package edu.ntnu.idatt2003.model.game;
 
-import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionException;
+import edu.ntnu.idatt2003.exceptions.EmptyListException;
+import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException;
+import edu.ntnu.idatt2003.exceptions.IsNullException;
 import edu.ntnu.idatt2003.model.math.mathModel.Vector2D;
 import edu.ntnu.idatt2003.model.math.transformation.Transform2D;
 import edu.ntnu.idatt2003.util.InputValidation;
@@ -21,23 +23,19 @@ public class ChaosGameDescription {
    * @param minCoords the minimum coordinates.
    * @param maxCoords the maximum coordinates.
    *
-   * @throws ChaosGameDescriptionException if the list of transforms is null,
-   *                                  if the list of transforms is empty,
-   *                                  if minCoords is null,
-   *                                  if maxCoords is null,
-   *                                  if minCoords is greater than or equal to maxCoords
+   * @throws IsNullException if any of the parameters are null.
+   * @throws EmptyListException if the list of transforms is empty.
+   * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the
+   *      maximum coordinates.
    */
   public ChaosGameDescription(List<Transform2D> transforms, Vector2D minCoords, Vector2D maxCoords)
-      throws ChaosGameDescriptionException {
-    try {
-      InputValidation.validateNotNull(transforms, "transforms");
-      InputValidation.validateListNotEmpty(transforms, "transforms");
-      InputValidation.validateNotNull(minCoords, "minCoords");
-      InputValidation.validateNotNull(maxCoords, "maxCoords");
-      validateCoordinates(minCoords, maxCoords);
-    } catch (IllegalArgumentException e) {
-      throw new ChaosGameDescriptionException("Invalid ChaosGameDescription", e);
-    }
+      throws IsNullException, EmptyListException, InvalidVectorRangeException {
+    InputValidation.validateNotNull(transforms, "transforms");
+    InputValidation.validateListNotEmpty(transforms, "transforms");
+    InputValidation.validateNotNull(minCoords, "minCoords");
+    InputValidation.validateNotNull(maxCoords, "maxCoords");
+    InputValidation.validateVectorRange(minCoords, maxCoords);
+
     this.transforms = transforms;
     this.minCoords = minCoords;
     this.maxCoords = maxCoords;
@@ -76,12 +74,12 @@ public class ChaosGameDescription {
    * @param minCoords the minimum coordinates.
    * @param maxCoords the maximum coordinates.
    *
-   * @throws ChaosGameDescriptionException if minCoords is greater than or equal to maxCoords
+   * @throws InvalidVectorRangeException if minCoords is greater than or equal to maxCoords
    */
   private void validateCoordinates(Vector2D minCoords, Vector2D maxCoords)
-      throws ChaosGameDescriptionException {
+      throws InvalidVectorRangeException {
     if (minCoords.getX0() >= maxCoords.getX0() || minCoords.getX1() >= maxCoords.getX1()) {
-      throw new ChaosGameDescriptionException("minCoords must be less than maxCoords");
+      throw new InvalidVectorRangeException("minCoords must be less than maxCoords");
     }
   }
 
diff --git a/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionFactory.java b/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionFactory.java
index 04ad1d0..f060b1a 100644
--- a/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionFactory.java
+++ b/src/main/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionFactory.java
@@ -1,7 +1,10 @@
 package edu.ntnu.idatt2003.model.game;
 
-import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionException;
-import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionFactoryException;
+import edu.ntnu.idatt2003.exceptions.EmptyListException;
+import edu.ntnu.idatt2003.exceptions.InvalidSignException;
+import edu.ntnu.idatt2003.exceptions.InvalidTypeException;
+import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException;
+import edu.ntnu.idatt2003.exceptions.IsNullException;
 import edu.ntnu.idatt2003.model.math.mathModel.Complex;
 import edu.ntnu.idatt2003.model.math.mathModel.Matrix2x2;
 import edu.ntnu.idatt2003.model.math.mathModel.Vector2D;
@@ -21,14 +24,21 @@ public class ChaosGameDescriptionFactory {
    *
    * @param type the type of chaos game to create.
    * @return a ChaosGameDescription object.
-   * @throws ChaosGameDescriptionFactoryException if the type is invalid.
+   * @throws InvalidTypeException if the transformation type is invalid.
+   * @throws EmptyListException if the list of transforms is empty.
+   * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the
+   *     maximum coordinates.
+   * @throws IsNullException if any of the parameters are null.
+   * @throws InvalidSignException if the sign of the vector is invalid.
    */
-  public static ChaosGameDescription get(String type) throws ChaosGameDescriptionFactoryException {
+  public static ChaosGameDescription get(String type)
+      throws EmptyListException, InvalidVectorRangeException,
+      InvalidSignException, IsNullException, InvalidTypeException {
     return switch (type) {
       case "Sierpinski" -> createSierpinskiTriangle();
       case "Barnsley" -> createBarnsleyFern();
       case "Julia Set" -> createJuliaSet();
-      default -> throw new ChaosGameDescriptionFactoryException("Invalid chaos game type");
+      default -> throw new InvalidTypeException("Invalid description type");
     };
   }
 
@@ -36,31 +46,37 @@ public class ChaosGameDescriptionFactory {
    * Helper method for creating a chaos game description of the Julia set.
    *
    * @return a list of the available chaos game types.
-   * @throws ChaosGameDescriptionFactoryException if an error occurs while creating the chaos game
+   * @throws EmptyListException if the list of transforms is empty.
+   * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the
+   *      maximum coordinates.
+   * @throws IsNullException if any of the parameters are null.
+   * @throws InvalidSignException if the sign of the vector is invalid.
    */
-  private static ChaosGameDescription createJuliaSet() throws ChaosGameDescriptionFactoryException {
+  private static ChaosGameDescription createJuliaSet()
+      throws EmptyListException, InvalidVectorRangeException, InvalidSignException,
+      IsNullException {
     List<Transform2D> transforms = List.of(
         new JuliaTransform(new Complex(0, 0.8), 1),
         new JuliaTransform(new Complex(0, 0.8), -1)
     );
     Vector2D minCoords = new Vector2D(-1.4, -1.4);
     Vector2D maxCoords = new Vector2D(1.4, 1.4);
-    try {
-      return new ChaosGameDescription(transforms, minCoords, maxCoords);
-    } catch (ChaosGameDescriptionException e) {
-      throw new ChaosGameDescriptionFactoryException(
-          "An error occurred while creating a ChaosGameDescription object in factory.", e);
-    }
+
+    return new ChaosGameDescription(transforms, minCoords, maxCoords);
   }
 
   /**
    * Helper method for creating a chaos game description of the Barnsley fern.
    *
    * @return a list of the available chaos game types.
-   * @throws ChaosGameDescriptionFactoryException if an error occurs while creating the chaos game
+   * @throws IsNullException if any of the parameters are null.
+   * @throws EmptyListException if the list of transforms is empty.
+   * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the
+   *      maximum coordinates.
    */
   private static ChaosGameDescription createBarnsleyFern()
-      throws ChaosGameDescriptionFactoryException {
+      throws IsNullException, EmptyListException,
+      InvalidVectorRangeException {
     List<Transform2D> transforms = List.of(
         new AffineTransform2D(new Matrix2x2(0, 0, 0, 0.16), new Vector2D(0, 0)),
         new AffineTransform2D(new Matrix2x2(0.85, 0.04, -0.04, 0.85), new Vector2D(0, 1.6)),
@@ -69,22 +85,22 @@ public class ChaosGameDescriptionFactory {
     );
     Vector2D minCoords = new Vector2D(-2.65, 0);
     Vector2D maxCoords = new Vector2D(2.65, 10);
-    try {
-      return new ChaosGameDescription(transforms, minCoords, maxCoords);
-    } catch (ChaosGameDescriptionException e) {
-      throw new ChaosGameDescriptionFactoryException(
-          "An error occurred while creating a ChaosGameDescription object in factory.", e);
-    }
+
+    return new ChaosGameDescription(transforms, minCoords, maxCoords);
   }
 
   /**
    * Helper method for creating a chaos game description of the Sierpinski triangle.
    *
    * @return a list of the available chaos game types.
-   * @throws ChaosGameDescriptionFactoryException if an error occurs while creating the chaos game
+   * @throws IsNullException if any of the parameters are null.
+   * @throws EmptyListException if the list of transforms is empty.
+   * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the
+   *     maximum coordinates.
    */
   private static ChaosGameDescription createSierpinskiTriangle()
-      throws ChaosGameDescriptionFactoryException {
+      throws IsNullException, EmptyListException,
+      InvalidVectorRangeException {
     List<Transform2D> transforms = List.of(
           new AffineTransform2D(new Matrix2x2(0.5, 0, 0, 0.5), new Vector2D(0, 0)),
           new AffineTransform2D(new Matrix2x2(0.5, 0, 0, 0.5), new Vector2D(0.5, 0)),
@@ -92,11 +108,8 @@ public class ChaosGameDescriptionFactory {
     );
     Vector2D minCoords = new Vector2D(0, 0);
     Vector2D maxCoords = new Vector2D(1, 1);
-    try {
-      return new ChaosGameDescription(transforms, minCoords, maxCoords);
-    } catch (ChaosGameDescriptionException e) {
-      throw new ChaosGameDescriptionFactoryException(
-          "An error occurred while creating a ChaosGameDescription object in factory.", e);
-    }
+
+    return new ChaosGameDescription(transforms, minCoords, maxCoords);
+
   }
 }
diff --git a/src/main/java/edu/ntnu/idatt2003/model/io/ChaosGameFileHandler.java b/src/main/java/edu/ntnu/idatt2003/model/io/ChaosGameFileHandler.java
index 5f64769..6490c29 100644
--- a/src/main/java/edu/ntnu/idatt2003/model/io/ChaosGameFileHandler.java
+++ b/src/main/java/edu/ntnu/idatt2003/model/io/ChaosGameFileHandler.java
@@ -1,8 +1,12 @@
 package edu.ntnu.idatt2003.model.io;
 
-import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionException;
-import edu.ntnu.idatt2003.exceptions.ChaosGameFileHandlerException;
+import edu.ntnu.idatt2003.exceptions.CouldNotWriteException;
+import edu.ntnu.idatt2003.exceptions.EmptyListException;
+import edu.ntnu.idatt2003.exceptions.InvalidSignException;
+import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException;
+import edu.ntnu.idatt2003.exceptions.IsNullException;
 import edu.ntnu.idatt2003.exceptions.WrongFileFormatException;
+import edu.ntnu.idatt2003.exceptions.WrongLengthException;
 import edu.ntnu.idatt2003.model.game.ChaosGameDescription;
 import edu.ntnu.idatt2003.model.math.mathModel.Complex;
 import edu.ntnu.idatt2003.model.math.mathModel.Matrix2x2;
@@ -34,24 +38,31 @@ public class ChaosGameFileHandler {
    *
    * @param file the file to be read.
    * @return the ChaosGameDescription read from the file.
-   * @throws ChaosGameFileHandlerException if the file is not found.
-   * @throws ChaosGameDescriptionException if the ChaosGameDescription could not be created.
+   * @throws FileNotFoundException if the file is not found.
+   * @throws WrongFileFormatException if the ChaosGameDescription could not be created.
+   * @throws IsNullException if an object is null.
+   * @throws EmptyListException if a list is empty.
+   * @throws InvalidVectorRangeException if the vector range is invalid.
+   * @throws InvalidSignException if the sign is invalid.
    */
   public ChaosGameDescription readFromFile(File file)
-      throws ChaosGameFileHandlerException {
+      throws WrongFileFormatException, IsNullException, EmptyListException,
+      InvalidVectorRangeException, InvalidSignException, FileNotFoundException {
     List<List<String>> lines = divideFileToLines(file);
-    if (lines.size() <= 3) {
-      throw new WrongFileFormatException();
+
+    try {
+      InputValidation.validateListLessOrEqualThan(lines, 3, "lines");
+    } catch (WrongLengthException e) {
+      throw new WrongFileFormatException("The file should have at least three lines", e);
     }
+
     List<String> type = lines.getFirst();
     try {
       InputValidation.validateNotNull(type, "type");
-    } catch (IllegalArgumentException e) {
+      InputValidation.validateListLength(type, 1, "type");
+    } catch (IsNullException | WrongLengthException e) {
       throw new WrongFileFormatException("The file should have one transformation type", e);
     }
-    if (type.size() != 1) {
-      throw new WrongFileFormatException("The file should have one transformation type");
-    }
     if (!type.getFirst().equals("Affine2D") && !type.getFirst().equals("Julia")) {
       throw new WrongFileFormatException("The file has an unsupported transformation type");
     }
@@ -61,12 +72,11 @@ public class ChaosGameFileHandler {
     try {
       InputValidation.validateNotNull(minCoords, "minCoords");
       InputValidation.validateNotNull(maxCoords, "maxCoords");
-    } catch (IllegalArgumentException e) {
+      InputValidation.validateListLength(minCoords, 2, "minCoords");
+      InputValidation.validateListLength(maxCoords, 2, "maxCoords");
+    } catch (IllegalArgumentException | WrongLengthException e) {
       throw new WrongFileFormatException("The file should have two min/max coordinates each", e);
     }
-    if (minCoords.size() != 2 || maxCoords.size() != 2) {
-      throw new WrongFileFormatException("The file should have two min/max coordinates each");
-    }
 
     double minX;
     double minY;
@@ -79,10 +89,7 @@ public class ChaosGameFileHandler {
       maxY = Double.parseDouble(maxCoords.get(1));
     } catch (NumberFormatException e) {
       throw new WrongFileFormatException("The min/max coordinates in the file are not numbers", e);
-    } catch (IndexOutOfBoundsException e) {
-      throw new WrongFileFormatException("The file is missing min/max coordinates", e);
     }
-
     if (minX >= maxX || minY >= maxY) {
       throw new WrongFileFormatException(
           "The min coordinates should be less than the max coordinates");
@@ -91,12 +98,9 @@ public class ChaosGameFileHandler {
     List<Transform2D> transforms =
         (type.getFirst().equals("Affine2D"))
             ? packageToAffineList(lines) : packageToJuliaList(lines);
-    try {
-      return new ChaosGameDescription(transforms, new Vector2D(minX, minY),
-          new Vector2D(maxX, maxY));
-    } catch (ChaosGameDescriptionException e) {
-      throw new ChaosGameFileHandlerException("Could not create ChaosGameDescription", e);
-    }
+
+    return new ChaosGameDescription(transforms, new Vector2D(minX, minY),
+        new Vector2D(maxX, maxY));
   }
 
   /**
@@ -104,10 +108,10 @@ public class ChaosGameFileHandler {
    *
    * @param file the file to divide.
    * @return a list of lines in the file.
-   * @throws ChaosGameFileHandlerException if the file is not found.
+   * @throws FileNotFoundException if the file is not found.
    */
   private List<List<String>> divideFileToLines(File file)
-      throws ChaosGameFileHandlerException {
+      throws FileNotFoundException {
     List<List<String>> lines = new ArrayList<>();
     try (Scanner scanner = new Scanner(file)) {
       scanner.useDelimiter("#.*|\n");
@@ -126,7 +130,7 @@ public class ChaosGameFileHandler {
         i++;
       }
     } catch (FileNotFoundException e) {
-      throw new ChaosGameFileHandlerException("File not found", e);
+      throw new FileNotFoundException("File not found");
     }
     return lines;
   }
@@ -141,9 +145,11 @@ public class ChaosGameFileHandler {
   private List<Transform2D> packageToAffineList(List<List<String>> lines)
       throws WrongFileFormatException {
     for (int i = 3; i < lines.size(); i++) {
-      if (lines.get(i).size() != 6) {
+      try {
+        InputValidation.validateListLength(lines.get(i), 6, "transformation");
+      } catch (WrongLengthException e) {
         throw new WrongFileFormatException(
-            "The file should have six values for each transformation");
+            "The file should have six values for each transformation", e);
       }
       for (String value : lines.get(i)) {
         try {
@@ -178,22 +184,28 @@ public class ChaosGameFileHandler {
    * @param lines the lines of the file.
    * @return a list of JuliaTransform.
    * @throws WrongFileFormatException if the file is not formatted correctly.
+   * @throws InvalidSignException if the sign is invalid.
    */
   private List<Transform2D> packageToJuliaList(List<List<String>> lines)
-      throws WrongFileFormatException {
+      throws WrongFileFormatException, InvalidSignException {
 
-    if (lines.size() != 4) {
-      throw new WrongFileFormatException("The file should have one Julia transformation");
+    try {
+      InputValidation.validateListLength(lines, 4, "Julia transformation");
+    } catch (WrongLengthException e) {
+      throw new WrongFileFormatException("The file should have one Julia transformation", e);
     }
+
     List<String> julia = lines.get(3);
     try {
       InputValidation.validateNotNull(julia, "Julia transformation");
-    } catch (IllegalArgumentException e) {
+    } catch (IsNullException e) {
       throw new WrongFileFormatException("The file should have one Julia transformation", e);
     }
 
-    if (julia.size() != 2) {
-      throw new WrongFileFormatException("The Julia transformation should have two values");
+    try {
+      InputValidation.validateListLength(julia, 2, "Julia transformation");
+    } catch (WrongLengthException e) {
+      throw new WrongFileFormatException("The Julia transformation should have two values", e);
     }
 
     double real;
@@ -219,10 +231,10 @@ public class ChaosGameFileHandler {
    *
    * @param chaosGameDescription the ChaosGameDescription to write.
    * @param path the path to the file.
-   * @throws ChaosGameFileHandlerException if the file could not be written to.
+   * @throws CouldNotWriteException if the file could not be written to.
    */
   public void writeToFile(ChaosGameDescription chaosGameDescription, File path)
-      throws ChaosGameFileHandlerException {
+      throws CouldNotWriteException {
     try (BufferedWriter writer = new BufferedWriter(new FileWriter(path))) {
       String type = chaosGameDescription.getTransforms().getFirst()
           instanceof AffineTransform2D ? "Affine2D" : "Julia";
@@ -246,7 +258,7 @@ public class ChaosGameFileHandler {
         writeJuliaToFile(writer, juliaTransform);
       }
     } catch (IOException e) {
-      throw new ChaosGameFileHandlerException("Could not write to file", e);
+      throw new CouldNotWriteException("Could not write to file", e);
     }
   }
 
@@ -255,10 +267,10 @@ public class ChaosGameFileHandler {
    *
    * @param writer the writer to write to.
    * @param affineTransform the AffineTransform2D to write.
-   * @throws IOException if the AffineTransform2D could not be written to the file.
+   * @throws CouldNotWriteException if the AffineTransform2D could not be written to the file.
    */
   private void writeAffineToFile(BufferedWriter writer, AffineTransform2D affineTransform)
-      throws IOException {
+      throws CouldNotWriteException {
     Matrix2x2 matrix = affineTransform.getMatrix();
     double a00 = matrix.getA00();
     double a01 = matrix.getA01();
@@ -269,7 +281,11 @@ public class ChaosGameFileHandler {
     double x0 = vector.getX0();
     double x1 = vector.getX1();
 
-    writer.write(a00 + ", " + a01 + ", " + a10 + ", " + a11 + ", " + x0 + ", " + x1 + "\n");
+    try {
+      writer.write(a00 + ", " + a01 + ", " + a10 + ", " + a11 + ", " + x0 + ", " + x1 + "\n");
+    } catch (IOException e) {
+      throw new CouldNotWriteException("Could not write to file", e);
+    }
   }
 
     /**
@@ -277,24 +293,28 @@ public class ChaosGameFileHandler {
      *
      * @param writer the writer to write to.
      * @param juliaTransform the JuliaTransform to write.
-     * @throws IOException if the JuliaTransform could not be written to the file.
+     * @throws CouldNotWriteException if the JuliaTransform could not be written to the file.
      */
   private void writeJuliaToFile(BufferedWriter writer, JuliaTransform juliaTransform)
-      throws IOException {
+      throws CouldNotWriteException {
     Complex complex = juliaTransform.getPoint();
     double real = complex.getX0();
     double imaginary = complex.getX1();
 
+    try {
     writer.write(real + ", " + imaginary + "\n");
+    } catch (IOException e) {
+      throw new CouldNotWriteException("Could not write to file", e);
+    }
   }
 
   /**
    * Lists all files in the resources directory.
    *
    * @return a list of all files in the resources directory.
-   * @throws ChaosGameFileHandlerException if the files could not be listed.
+   * @throws IOException if the files could not be listed.
    */
-  public List<String> listFiles() throws ChaosGameFileHandlerException {
+  public List<String> listFiles() throws IOException {
     List<String> fileList = new ArrayList<>();
     try {
       Path resourceDirectory = Paths.get("src/main/resources");
@@ -304,7 +324,7 @@ public class ChaosGameFileHandler {
             .forEach(path -> fileList.add(path.toString()));
       }
     } catch (IOException e) {
-      throw new ChaosGameFileHandlerException("Could not list files", e);
+      throw new IOException("Could not list files");
     }
     return fileList;
   }
diff --git a/src/main/java/edu/ntnu/idatt2003/model/math/transformation/JuliaTransform.java b/src/main/java/edu/ntnu/idatt2003/model/math/transformation/JuliaTransform.java
index 4f29c6c..529de0f 100644
--- a/src/main/java/edu/ntnu/idatt2003/model/math/transformation/JuliaTransform.java
+++ b/src/main/java/edu/ntnu/idatt2003/model/math/transformation/JuliaTransform.java
@@ -1,5 +1,6 @@
 package edu.ntnu.idatt2003.model.math.transformation;
 
+import edu.ntnu.idatt2003.exceptions.InvalidSignException;
 import edu.ntnu.idatt2003.model.math.mathModel.Complex;
 import edu.ntnu.idatt2003.model.math.mathModel.Vector2D;
 
@@ -17,12 +18,12 @@ public class JuliaTransform  implements Transform2D {
    * @param point the point to transform around.
    * @param sign the sign of the transformation.
    *
-   * @throws IllegalArgumentException if sign is not 1 or -1.
+   * @throws InvalidSignException if sign is not 1 or -1.
    */
-  public JuliaTransform(Complex point, int sign) {
+  public JuliaTransform(Complex point, int sign) throws InvalidSignException {
     this.point = point;
     if (sign != 1 && sign != -1) {
-      throw new IllegalArgumentException("Sign must be 1 or -1");
+      throw new InvalidSignException("Sign must be 1 or -1");
     }
     this.sign = sign;
   }
diff --git a/src/main/java/edu/ntnu/idatt2003/util/InputValidation.java b/src/main/java/edu/ntnu/idatt2003/util/InputValidation.java
index 0505244..433b20e 100644
--- a/src/main/java/edu/ntnu/idatt2003/util/InputValidation.java
+++ b/src/main/java/edu/ntnu/idatt2003/util/InputValidation.java
@@ -1,5 +1,11 @@
 package edu.ntnu.idatt2003.util;
 
+import edu.ntnu.idatt2003.exceptions.EmptyListException;
+import edu.ntnu.idatt2003.exceptions.InvalidPositiveIntException;
+import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException;
+import edu.ntnu.idatt2003.exceptions.IsNullException;
+import edu.ntnu.idatt2003.exceptions.WrongLengthException;
+import edu.ntnu.idatt2003.model.math.mathModel.Vector2D;
 import java.util.List;
 
 /**
@@ -13,12 +19,12 @@ public class InputValidation {
    *
    * @param object to be validated
    * @param parameterName the name of the object
-   * @throws IllegalArgumentException if the object is null
+   * @throws IsNullException if the object is null
    */
   public static void validateNotNull(Object object, String parameterName)
-      throws IllegalArgumentException {
+      throws IsNullException {
     if (object == null) {
-      throw new IllegalArgumentException("Object: " + parameterName + " cannot be null");
+      throw new IsNullException("Object: " + parameterName + " cannot be null");
     }
   }
 
@@ -27,12 +33,12 @@ public class InputValidation {
    *
    * @param number to be validated
    * @param parameterName the name of the int
-   * @throws IllegalArgumentException if the int is not positive
+   * @throws InvalidPositiveIntException if the int is not positive
    */
   public static void validatePositiveInt(int number, String parameterName)
-      throws IllegalArgumentException {
+      throws InvalidPositiveIntException {
     if (number <= 0) {
-      throw new IllegalArgumentException("Number: " + parameterName + " must be positive");
+      throw new InvalidPositiveIntException("Number: " + parameterName + " must be positive");
     }
   }
 
@@ -41,12 +47,59 @@ public class InputValidation {
    *
    * @param list to be validated
    * @param parameterName the name of the list
-   * @throws IllegalArgumentException if the list is empty
+   * @throws EmptyListException if the list is empty
    */
   public static <T> void validateListNotEmpty(List<T> list, String parameterName)
-      throws IllegalArgumentException {
+      throws EmptyListException {
     if (list.isEmpty()) {
-      throw new IllegalArgumentException("List: " + parameterName + " must not be empty");
+      throw new EmptyListException("List: " + parameterName + " must not be empty");
+    }
+  }
+
+  /**
+   * Validates that a list is less or equal to a given size.
+   *
+   * @param list to be validated
+   * @param size the maximum size of the list
+   * @param parameterName the name of the list
+   * @throws WrongLengthException if the list is bigger than the given size
+   */
+  public static void validateListLessOrEqualThan(List<?> list, int size, String parameterName)
+      throws WrongLengthException {
+    if (list.size() <= size) {
+      throw new WrongLengthException("List: " + parameterName
+          + " must have at least " + size + " elements");
+    }
+  }
+
+  /**
+   * Validates that a list is exactly a given size.
+   *
+   * @param list to be validated
+   * @param size the size of the list
+   * @param parameterName the name of the list
+   * @throws WrongLengthException if the list is not the given size
+   */
+  public static void validateListLength(List<?> list, int size, String parameterName)
+      throws WrongLengthException {
+    if (list.size() != size) {
+      throw new WrongLengthException("List: " + parameterName
+          + " must have exactly " + size + " elements");
+    }
+  }
+
+  /**
+   * Validates that the minimum coordinates are less than the maximum coordinates.
+   *
+   * @param minCoords the minimum coordinates
+   * @param maxCoords the maximum coordinates
+   * @throws InvalidVectorRangeException if the minimum coordinates are greater than or equal to the
+   *     maximum coordinates
+   */
+  public static void validateVectorRange(Vector2D minCoords, Vector2D maxCoords)
+      throws InvalidVectorRangeException {
+    if (minCoords.getX0() >= maxCoords.getX0() || minCoords.getX1() >= maxCoords.getX1()) {
+      throw new InvalidVectorRangeException("Minimum coordinates must be less than maximum coordinates");
     }
   }
 }
diff --git a/src/test/java/edu/ntnu/idatt2003/model/game/ChaosCanvasTest.java b/src/test/java/edu/ntnu/idatt2003/model/game/ChaosCanvasTest.java
index a38ec50..e6ab5eb 100644
--- a/src/test/java/edu/ntnu/idatt2003/model/game/ChaosCanvasTest.java
+++ b/src/test/java/edu/ntnu/idatt2003/model/game/ChaosCanvasTest.java
@@ -2,7 +2,9 @@ package edu.ntnu.idatt2003.model.game;
 
 import static org.junit.jupiter.api.Assertions.*;
 
-import edu.ntnu.idatt2003.exceptions.ChaosCanvasException;
+import edu.ntnu.idatt2003.exceptions.InvalidPositiveIntException;
+import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException;
+import edu.ntnu.idatt2003.exceptions.IsNullException;
 import edu.ntnu.idatt2003.model.math.mathModel.Vector2D;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.DisplayName;
@@ -20,7 +22,8 @@ class ChaosCanvasTest {
 
     ChaosCanvas canvas;
     @BeforeEach
-    public void setUp() throws ChaosCanvasException {
+    public void setUp() throws InvalidPositiveIntException, IsNullException,
+        InvalidVectorRangeException {
       canvas = new ChaosCanvas(100, 100, new Vector2D(0, 0), new Vector2D(200, 200));
     }
 
@@ -102,14 +105,18 @@ class ChaosCanvasTest {
     public class PositiveTestsForEquals {
       @Test
       @DisplayName("Equals returns true when two canvases are equal")
-      void equalsReturnsTrueWhenTwoCanvasesAreEqual() throws ChaosCanvasException {
+      void equalsReturnsTrueWhenTwoCanvasesAreEqual()
+          throws InvalidPositiveIntException, IsNullException,
+          InvalidVectorRangeException {
         ChaosCanvas canvas2 = new ChaosCanvas(100, 100, new Vector2D(0, 0), new Vector2D(200, 200));
         assertEquals(canvas, canvas2);
       }
 
       @Test
       @DisplayName("Equals returns false when two canvases are not equal")
-      void equalsReturnsFalseWhenTwoCanvasesAreNotEqual() throws ChaosCanvasException {
+      void equalsReturnsFalseWhenTwoCanvasesAreNotEqual()
+          throws InvalidPositiveIntException, IsNullException,
+          InvalidVectorRangeException {
         ChaosCanvas canvas2 = new ChaosCanvas(120, 120, new Vector2D(1, 1), new Vector2D(100, 100));
         assertNotEquals(canvas, canvas2);
       }
@@ -134,10 +141,12 @@ class ChaosCanvasTest {
 
     @Test
     @DisplayName("Negative tests for setMinMaxCoords")
-    public void setMinMaxCoordsThrowsExceptionOnNull() throws ChaosCanvasException {
+    public void setMinMaxCoordsThrowsExceptionOnNull()
+        throws InvalidPositiveIntException, IsNullException,
+        InvalidVectorRangeException {
       ChaosCanvas canvas = new ChaosCanvas(100, 100, new Vector2D(0, 0), new Vector2D(200, 200));
-      assertThrows(ChaosCanvasException.class, () -> canvas.setMinMaxCoords(null, new Vector2D(200, 200)));
-      assertThrows(ChaosCanvasException.class, () -> canvas.setMinMaxCoords(new Vector2D(0, 0), null));
+      assertThrows(IsNullException.class, () -> canvas.setMinMaxCoords(null, new Vector2D(200, 200)));
+      assertThrows(IsNullException.class, () -> canvas.setMinMaxCoords(new Vector2D(0, 0), null));
     }
 
     @Nested
@@ -147,13 +156,13 @@ class ChaosCanvasTest {
       @Test
       @DisplayName("Constructor throws exception on negative width")
       public void constructorThrowsExceptionOnNegativeWidth() {
-        assertThrows(ChaosCanvasException.class, () -> new ChaosCanvas(-100, 100, new Vector2D(0, 0), new Vector2D(200, 200)));
+        assertThrows(InvalidPositiveIntException.class, () -> new ChaosCanvas(-100, 100, new Vector2D(0, 0), new Vector2D(200, 200)));
       }
 
       @Test
       @DisplayName("Constructor throws exception on negative height")
       public void constructorThrowsExceptionOnNegativeHeight() {
-        assertThrows(ChaosCanvasException.class, () -> new ChaosCanvas(100, -100, new Vector2D(0, 0), new Vector2D(200, 200)));
+        assertThrows(InvalidPositiveIntException.class, () -> new ChaosCanvas(100, -100, new Vector2D(0, 0), new Vector2D(200, 200)));
       }
     }
   }
diff --git a/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionFactoryTest.java b/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionFactoryTest.java
index cfb14bc..281b3f5 100644
--- a/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionFactoryTest.java
+++ b/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionFactoryTest.java
@@ -2,7 +2,11 @@ package edu.ntnu.idatt2003.model.game;
 
 import static org.junit.jupiter.api.Assertions.*;
 
-import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionFactoryException;
+import edu.ntnu.idatt2003.exceptions.EmptyListException;
+import edu.ntnu.idatt2003.exceptions.InvalidSignException;
+import edu.ntnu.idatt2003.exceptions.InvalidTypeException;
+import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException;
+import edu.ntnu.idatt2003.exceptions.IsNullException;
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
@@ -18,7 +22,8 @@ class ChaosGameDescriptionFactoryTest {
     @Test
     @DisplayName("get Sierpinski returns a ChaosGameDescription object")
     public void getSierpinskiReturnsCorrectDescription()
-        throws ChaosGameDescriptionFactoryException {
+        throws InvalidSignException, IsNullException,
+        EmptyListException, InvalidVectorRangeException, InvalidTypeException {
       ChaosGameDescription chaosGameDescription = ChaosGameDescriptionFactory.get("Sierpinski");
       assertNotNull(chaosGameDescription);
     }
@@ -26,7 +31,8 @@ class ChaosGameDescriptionFactoryTest {
     @Test
     @DisplayName("get Barnsley returns a ChaosGameDescription object")
     public void getBarnsleyReturnsCorrectDescription()
-        throws ChaosGameDescriptionFactoryException {
+        throws InvalidSignException, IsNullException,
+        EmptyListException, InvalidVectorRangeException, InvalidTypeException {
       ChaosGameDescription chaosGameDescription = ChaosGameDescriptionFactory.get("Barnsley");
       assertNotNull(chaosGameDescription);
     }
@@ -34,7 +40,8 @@ class ChaosGameDescriptionFactoryTest {
     @Test
     @DisplayName("get Julia Set returns a ChaosGameDescription object")
     public void getJuliaSetReturnsCorrectDescription()
-        throws ChaosGameDescriptionFactoryException {
+        throws InvalidSignException, IsNullException,
+        EmptyListException, InvalidVectorRangeException, InvalidTypeException {
       ChaosGameDescription chaosGameDescription = ChaosGameDescriptionFactory.get("Julia Set");
       assertNotNull(chaosGameDescription);
     }
@@ -44,9 +51,9 @@ class ChaosGameDescriptionFactoryTest {
   @DisplayName("Negative tests")
   class MethodsThrowsException {
     @Test
-    @DisplayName("get with invalid type throws ChaosGameDescriptionFactoryException")
+    @DisplayName("get with invalid type throws InvalidTypeException")
     public void getWithInvalidTypeThrowsException() {
-      assertThrows(ChaosGameDescriptionFactoryException.class, () -> ChaosGameDescriptionFactory.get("Invalid"));
+      assertThrows(InvalidTypeException.class, () -> ChaosGameDescriptionFactory.get("Invalid"));
     }
   }
 }
\ No newline at end of file
diff --git a/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionTest.java b/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionTest.java
index 55f5782..1ead946 100644
--- a/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionTest.java
+++ b/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameDescriptionTest.java
@@ -1,6 +1,9 @@
 package edu.ntnu.idatt2003.model.game;
 
-import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionException;
+import edu.ntnu.idatt2003.exceptions.EmptyListException;
+import edu.ntnu.idatt2003.exceptions.InvalidSignException;
+import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException;
+import edu.ntnu.idatt2003.exceptions.IsNullException;
 import edu.ntnu.idatt2003.model.math.mathModel.Complex;
 import edu.ntnu.idatt2003.model.math.mathModel.Vector2D;
 import edu.ntnu.idatt2003.model.math.transformation.JuliaTransform;
@@ -26,7 +29,8 @@ class ChaosGameDescriptionTest {
     Vector2D maxCoords;
 
     @BeforeEach
-    public void setUp() throws ChaosGameDescriptionException {
+    public void setUp() throws InvalidSignException, IsNullException, EmptyListException,
+        InvalidVectorRangeException {
       transforms = List.of(
           new JuliaTransform(new Complex(-0.74543, 0.11301), 1),
           new JuliaTransform(new Complex(-0.74543, 0.11301), -1)
@@ -59,14 +63,18 @@ class ChaosGameDescriptionTest {
     public class PositiveTestsForEquals {
       @Test
       @DisplayName("Equals returns true when two descriptions are equal")
-      void equalsReturnsTrueWhenTwoDescriptionsAreEqual() throws ChaosGameDescriptionException {
+      void equalsReturnsTrueWhenTwoDescriptionsAreEqual()
+          throws IsNullException, EmptyListException,
+          InvalidVectorRangeException {
         ChaosGameDescription description2 = new ChaosGameDescription(transforms, minCoords, maxCoords);
         assertEquals(description, description2);
       }
 
       @Test
       @DisplayName("Equals returns false when two descriptions are not equal")
-      void equalsReturnsFalseWhenTwoDescriptionsAreNotEqual() throws ChaosGameDescriptionException {
+      void equalsReturnsFalseWhenTwoDescriptionsAreNotEqual()
+          throws InvalidSignException, IsNullException, EmptyListException,
+          InvalidVectorRangeException {
         List<Transform2D> transforms2 = List.of(
             new JuliaTransform(new Complex(-0.7, 0.301), 1),
             new JuliaTransform(new Complex(-0.7, 0.301), -1)
@@ -95,37 +103,37 @@ class ChaosGameDescriptionTest {
   @DisplayName("Negative tests")
   class MethodsThrowsExceptions {
     @Test
-    @DisplayName("Test constructor throws ChaosGameDescriptionException if transforms is null")
+    @DisplayName("Test constructor throws IsNullException if transforms is null")
     public void testConstructorTransformsIsNull() {
-      assertThrows(ChaosGameDescriptionException.class, () -> new ChaosGameDescription(
+      assertThrows(IsNullException.class, () -> new ChaosGameDescription(
           null, new Vector2D(0, 0), new Vector2D(1, 1)));
     }
 
     @Test
-    @DisplayName("Test constructor throws ChaosGameDescriptionException if transforms is empty")
+    @DisplayName("Test constructor throws EmptyListException if transforms is empty")
     public void testConstructorTransformsIsEmpty() {
-      assertThrows(ChaosGameDescriptionException.class, () -> new ChaosGameDescription(
+      assertThrows(EmptyListException.class, () -> new ChaosGameDescription(
           List.of(), new Vector2D(0, 0), new Vector2D(1, 1)));
     }
 
     @Test
-    @DisplayName("Test constructor throws ChaosGameDescriptionException if minCoords is null")
+    @DisplayName("Test constructor throws IsNullException if minCoords is null")
     public void testConstructorIfMinCoordsIsNull() {
-      assertThrows(ChaosGameDescriptionException.class, () -> new ChaosGameDescription(
+      assertThrows(IsNullException.class, () -> new ChaosGameDescription(
           List.of(new JuliaTransform(new Complex(0, 0), 1)), null, new Vector2D(1, 1)));
     }
 
     @Test
-    @DisplayName("Test constructor throws ChaosGameDescriptionException if maxCoords is null")
+    @DisplayName("Test constructor throws IsNullException if maxCoords is null")
     public void testConstructorMaxCoordsIsNull() {
-      assertThrows(ChaosGameDescriptionException.class, () -> new ChaosGameDescription(
+      assertThrows(IsNullException.class, () -> new ChaosGameDescription(
           List.of(new JuliaTransform(new Complex(0, 0), 1)), new Vector2D(0, 0), null));
     }
 
     @Test
-    @DisplayName("Test constructor throws ChaosGameDescriptionException if minCoords is greater than maxCoords")
+    @DisplayName("Test constructor throws InvalidVectorRangeException if minCoords is greater than maxCoords")
     public void testConstructorMinCoordsIsGreaterThanMaxCoords() {
-      assertThrows(ChaosGameDescriptionException.class, () -> new ChaosGameDescription(
+      assertThrows(InvalidVectorRangeException.class, () -> new ChaosGameDescription(
           List.of(new JuliaTransform(new Complex(0, 0), 1)), new Vector2D(1, 1), new Vector2D(0, 0)));
     }
   }
diff --git a/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameTest.java b/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameTest.java
index c82810b..b802ef1 100644
--- a/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameTest.java
+++ b/src/test/java/edu/ntnu/idatt2003/model/game/ChaosGameTest.java
@@ -2,13 +2,12 @@ package edu.ntnu.idatt2003.model.game;
 
 import static org.junit.jupiter.api.Assertions.*;
 
-import edu.ntnu.idatt2003.exceptions.ChaosCanvasException;
-import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionException;
-import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionFactoryException;
-import edu.ntnu.idatt2003.exceptions.ChaosGameException;
-import edu.ntnu.idatt2003.model.math.transformation.AffineTransform2D;
-import edu.ntnu.idatt2003.model.math.transformation.Transform2D;
-import java.util.List;
+import edu.ntnu.idatt2003.exceptions.EmptyListException;
+import edu.ntnu.idatt2003.exceptions.InvalidPositiveIntException;
+import edu.ntnu.idatt2003.exceptions.InvalidSignException;
+import edu.ntnu.idatt2003.exceptions.InvalidTypeException;
+import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException;
+import edu.ntnu.idatt2003.exceptions.IsNullException;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.DisplayName;
 import org.junit.jupiter.api.Nested;
@@ -26,8 +25,9 @@ class ChaosGameTest {
     @Test
     @DisplayName("Constructor creates a ChaosGame object")
     void constructorDoesNotThrowExceptionOnValidParameters()
-        throws ChaosGameDescriptionFactoryException, ChaosGameDescriptionException,
-        ChaosGameException, ChaosCanvasException {
+        throws InvalidSignException, IsNullException,
+        EmptyListException, InvalidVectorRangeException, InvalidTypeException,
+        InvalidPositiveIntException {
       ChaosGameDescription description = ChaosGameDescriptionFactory.get("Sierpinski");
       ChaosGame chaosGame = new ChaosGame(description, 100, 100);
       assertNotNull(chaosGame);
@@ -39,8 +39,9 @@ class ChaosGameTest {
       ChaosGame chaosGame;
 
       @BeforeEach
-      void setUp() throws ChaosGameDescriptionFactoryException, ChaosGameDescriptionException,
-        ChaosGameException, ChaosCanvasException {
+      void setUp() throws InvalidSignException, IsNullException,
+          EmptyListException, InvalidVectorRangeException, InvalidTypeException,
+          InvalidPositiveIntException {
         ChaosGameDescription description = ChaosGameDescriptionFactory.get("Sierpinski");
         chaosGame = new ChaosGame(description, 100, 100);
       }
@@ -54,7 +55,8 @@ class ChaosGameTest {
       @Test
       @DisplayName("resetGameWithNewDescription does not throw exception on valid parameters")
       void resetGameWithNewDescriptionDoesNotThrowException()
-        throws ChaosGameDescriptionFactoryException {
+          throws InvalidSignException, IsNullException,
+          EmptyListException, InvalidVectorRangeException, InvalidTypeException {
         ChaosGameDescription description = ChaosGameDescriptionFactory.get("Julia Set");
         assertDoesNotThrow(() -> chaosGame.resetGameWithDescription(description));
       }
@@ -72,28 +74,30 @@ class ChaosGameTest {
   class MethodsThrowsExceptionOnInvalidParameters {
 
     @Test
-    @DisplayName("Constructor throws ChaosGameException on null description")
-    void constructorThrowsChaosGameExceptionOnNullDescription() {
-      assertThrows(ChaosGameException.class, () -> new ChaosGame(null, 100, 100));
+    @DisplayName("Constructor throws IsNullException on null description")
+    void constructorThrowsIsNullExceptionOnNullDescription() {
+      assertThrows(IsNullException.class, () -> new ChaosGame(null, 100, 100));
     }
 
     @Test
-    @DisplayName("resetGameWithNewDescription throws ChaosGameException on null description")
-    void resetGameWithNewDescriptionThrowsChaosGameExceptionOnNullDescription()
-      throws ChaosGameDescriptionFactoryException, ChaosGameException {
+    @DisplayName("resetGameWithNewDescription throws IsNullException on null description")
+    void resetGameWithNewDescriptionThrowsIsNullExceptionOnNullDescription()
+        throws InvalidSignException,
+        IsNullException, EmptyListException, InvalidVectorRangeException, InvalidTypeException,
+        InvalidPositiveIntException {
       ChaosGameDescription description = ChaosGameDescriptionFactory.get("Sierpinski");
       ChaosGame chaosGame = new ChaosGame(description, 100, 100);
-      assertThrows(ChaosGameException.class, () -> chaosGame.resetGameWithDescription(null));
+      assertThrows(IsNullException.class, () -> chaosGame.resetGameWithDescription(null));
     }
 
     @Test
-    @DisplayName("runSteps throws ChaosGameException on negative steps")
-    void runStepsThrowsChaosGameExceptionOnNegativeSteps()
-      throws ChaosGameDescriptionFactoryException,
-      ChaosGameException {
+    @DisplayName("runSteps throws InvalidPositiveIntException on negative steps")
+    void runStepsThrowsInvalidPositiveIntExceptionOnNegativeSteps()
+        throws InvalidSignException, IsNullException, EmptyListException,
+        InvalidVectorRangeException, InvalidTypeException, InvalidPositiveIntException {
       ChaosGameDescription description = ChaosGameDescriptionFactory.get("Sierpinski");
       ChaosGame chaosGame = new ChaosGame(description, 100, 100);
-      assertThrows(ChaosGameException.class, () -> chaosGame.runSteps(0));
+      assertThrows(InvalidPositiveIntException.class, () -> chaosGame.runSteps(0));
     }
   }
 }
\ No newline at end of file
diff --git a/src/test/java/edu/ntnu/idatt2003/model/io/ChaosGameFileHandlerTest.java b/src/test/java/edu/ntnu/idatt2003/model/io/ChaosGameFileHandlerTest.java
index 2ab3432..a14c083 100644
--- a/src/test/java/edu/ntnu/idatt2003/model/io/ChaosGameFileHandlerTest.java
+++ b/src/test/java/edu/ntnu/idatt2003/model/io/ChaosGameFileHandlerTest.java
@@ -2,8 +2,11 @@ package edu.ntnu.idatt2003.model.io;
 
 import static org.junit.jupiter.api.Assertions.*;
 
-import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionException;
-import edu.ntnu.idatt2003.exceptions.ChaosGameFileHandlerException;
+import edu.ntnu.idatt2003.exceptions.CouldNotWriteException;
+import edu.ntnu.idatt2003.exceptions.EmptyListException;
+import edu.ntnu.idatt2003.exceptions.InvalidSignException;
+import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException;
+import edu.ntnu.idatt2003.exceptions.IsNullException;
 import edu.ntnu.idatt2003.exceptions.WrongFileFormatException;
 import edu.ntnu.idatt2003.model.game.ChaosGameDescription;
 import edu.ntnu.idatt2003.model.math.mathModel.Complex;
@@ -12,6 +15,7 @@ import edu.ntnu.idatt2003.model.math.mathModel.Vector2D;
 import edu.ntnu.idatt2003.model.math.transformation.AffineTransform2D;
 import edu.ntnu.idatt2003.model.math.transformation.JuliaTransform;
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.util.List;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.DisplayName;
@@ -37,7 +41,8 @@ class ChaosGameFileHandlerTest {
     ChaosGameDescription affine2DPositive;
 
     @BeforeEach
-    void setUp() throws ChaosGameDescriptionException {
+    void setUp() throws IsNullException, EmptyListException,
+        InvalidVectorRangeException, InvalidSignException {
       Vector2D vector1 = new Vector2D(0, 0);
       Vector2D vector2 = new Vector2D(0, 1.6);
       Vector2D vector3 = new Vector2D(0, 1.6);
@@ -63,7 +68,9 @@ class ChaosGameFileHandlerTest {
     @Test
     @DisplayName("Test if readFromFile reads affine transformations correctly")
     void testIfReadChaosGameFileReadsAffineTransformationsCorrectly()
-        throws ChaosGameFileHandlerException, ChaosGameDescriptionException {
+        throws InvalidSignException,
+        WrongFileFormatException, IsNullException, FileNotFoundException, EmptyListException,
+        InvalidVectorRangeException {
       File file = new File("src/test/resources/Affine2DReadPositive.txt");
       ChaosGameDescription chaosGameDescription = chaosGameFileHandler.readFromFile(file);
 
@@ -73,7 +80,8 @@ class ChaosGameFileHandlerTest {
     @Test
     @DisplayName("Test if readFromFile reads julia transformations correctly")
     void testIfReadChaosGameFileReadsJuliaTransformationsCorrectly()
-        throws ChaosGameFileHandlerException, ChaosGameDescriptionException {
+        throws InvalidSignException, WrongFileFormatException, IsNullException,
+        FileNotFoundException, EmptyListException, InvalidVectorRangeException {
       File file = new File("src/test/resources/JuliaReadPositive.txt");
       ChaosGameDescription chaosGameDescription = chaosGameFileHandler.readFromFile(file);
 
@@ -83,7 +91,8 @@ class ChaosGameFileHandlerTest {
     @Test
     @DisplayName("Test if writeToFile writes affine transformations correctly")
     void testIfWriteChaosGameFileWritesAffineTransformationsCorrectly()
-        throws ChaosGameFileHandlerException, ChaosGameDescriptionException {
+        throws CouldNotWriteException, InvalidSignException, WrongFileFormatException,
+        IsNullException, FileNotFoundException, EmptyListException, InvalidVectorRangeException {
       File file = new File("src/test/resources/Affine2DWritePositive.txt");
       chaosGameFileHandler.writeToFile(affine2DPositive, file);
       ChaosGameDescription chaosGameDescription = chaosGameFileHandler.readFromFile(file);
@@ -95,7 +104,8 @@ class ChaosGameFileHandlerTest {
     @Test
     @DisplayName("Test if writeToFile writes julia transformations correctly")
     void testIfWriteChaosGameFileWritesJuliaTransformationsCorrectly()
-        throws ChaosGameFileHandlerException, ChaosGameDescriptionException {
+        throws CouldNotWriteException, InvalidSignException, WrongFileFormatException, IsNullException,
+        FileNotFoundException, EmptyListException, InvalidVectorRangeException {
       File file = new File("src/test/resources/JuliaWritePositive.txt");
       chaosGameFileHandler.writeToFile(juliaPositive, file);
       ChaosGameDescription chaosGameDescription = chaosGameFileHandler.readFromFile(file);
diff --git a/src/test/java/edu/ntnu/idatt2003/model/math/transformation/JuliaTransformTest.java b/src/test/java/edu/ntnu/idatt2003/model/math/transformation/JuliaTransformTest.java
index 9f40040..22e6f64 100644
--- a/src/test/java/edu/ntnu/idatt2003/model/math/transformation/JuliaTransformTest.java
+++ b/src/test/java/edu/ntnu/idatt2003/model/math/transformation/JuliaTransformTest.java
@@ -2,6 +2,7 @@ package edu.ntnu.idatt2003.model.math.transformation;
 
 import static org.junit.jupiter.api.Assertions.*;
 
+import edu.ntnu.idatt2003.exceptions.InvalidSignException;
 import edu.ntnu.idatt2003.model.math.mathModel.Complex;
 import edu.ntnu.idatt2003.model.math.mathModel.Vector2D;
 import org.junit.jupiter.api.DisplayName;
@@ -20,7 +21,7 @@ class JuliaTransformTest {
 
       @Test
       @DisplayName("Transform returns correct values, test 1")
-      void transformReturnsCorrectValues1() {
+      void transformReturnsCorrectValues1() throws InvalidSignException {
         JuliaTransform juliaTransform = new JuliaTransform(new Complex(3, 2), 1);
         Vector2D vector = new Vector2D(4, 1);
         Vector2D vector2 = juliaTransform.transform(vector);
@@ -30,7 +31,7 @@ class JuliaTransformTest {
 
       @Test
       @DisplayName("Transform returns correct values, test 2")
-      void transformReturnsCorrectValues2() {
+      void transformReturnsCorrectValues2() throws InvalidSignException {
         JuliaTransform juliaTransform = new JuliaTransform(new Complex(-2, 3), 1);
         Vector2D vector = new Vector2D(0, 3);
         Vector2D vector2 = juliaTransform.transform(vector);
@@ -40,7 +41,7 @@ class JuliaTransformTest {
 
       @Test
       @DisplayName("Transform returns correct values, test 3")
-      void transformReturnsCorrectValues3() {
+      void transformReturnsCorrectValues3() throws InvalidSignException {
         JuliaTransform juliaTransform = new JuliaTransform(new Complex(4, 5), 1);
         Vector2D vector = new Vector2D(2, 1);
         Vector2D vector2 = juliaTransform.transform(vector);
@@ -54,7 +55,7 @@ class JuliaTransformTest {
     public class PositiveTestsForEquals {
       @Test
       @DisplayName("Equals returns true when two julia are equal")
-      void equalsReturnsTrueWhenTwoJuliaAreEqual() {
+      void equalsReturnsTrueWhenTwoJuliaAreEqual() throws InvalidSignException {
         Complex complex = new Complex(3, 2);
         JuliaTransform julia1 = new JuliaTransform(complex, 1);
         JuliaTransform julia2 = new JuliaTransform(complex, 1);
@@ -63,7 +64,7 @@ class JuliaTransformTest {
 
       @Test
       @DisplayName("Equals returns false when two julia are not equal")
-      void equalsReturnsFalseWhenTwoJuliaAreNotEqual() {
+      void equalsReturnsFalseWhenTwoJuliaAreNotEqual() throws InvalidSignException {
         Complex complex1 = new Complex(3, 2);
         Complex complex2 = new Complex(4, 1);
         JuliaTransform julia1 = new JuliaTransform(complex1, 1);
@@ -73,7 +74,7 @@ class JuliaTransformTest {
 
       @Test
       @DisplayName("Equals returns false when comparing a vector to null")
-      void equalsReturnsFalseWhenComparingAVectorToNull() {
+      void equalsReturnsFalseWhenComparingAVectorToNull() throws InvalidSignException {
         Complex complex = new Complex(3, 2);
         JuliaTransform julia = new JuliaTransform(complex, 1);
         assertNotEquals(julia, null);
@@ -81,7 +82,7 @@ class JuliaTransformTest {
 
       @Test
       @DisplayName("Equals returns false when comparing a vector to a different object")
-      void equalsReturnsFalseWhenComparingAVectorToADifferentObject() {
+      void equalsReturnsFalseWhenComparingAVectorToADifferentObject() throws InvalidSignException {
         Complex complex = new Complex(3, 2);
         JuliaTransform julia = new JuliaTransform(complex, 1);
         assertNotEquals(julia, new Object());
@@ -94,9 +95,9 @@ class JuliaTransformTest {
     public class MethodsThrowsExceptions {
 
       @Test
-      @DisplayName("Constructor throws IllegalArgumentException if sign is not 1 or -1")
-      void constructorThrowsIllegalArgumentException() {
-        assertThrows(IllegalArgumentException.class, () -> new JuliaTransform(new Complex(3, 2), 0));
+      @DisplayName("Constructor throws InvalidSignException if sign is not 1 or -1")
+      void constructorThrowsInvalidSignException() {
+        assertThrows(InvalidSignException.class, () -> new JuliaTransform(new Complex(3, 2), 0));
       }
     }
 }
\ No newline at end of file
-- 
GitLab


From d3a5f26cf431e02f64d431b9da0851479443713d Mon Sep 17 00:00:00 2001
From: Vetle <vetletb@stud.ntnu.no>
Date: Thu, 16 May 2024 13:16:19 +0200
Subject: [PATCH 3/3] Added exception handling

---
 .../controller/ChaosGameController.java       | 105 +++++++++++++-----
 .../idatt2003/view/CommandLineInterface.java  |  60 ++++++----
 .../idatt2003/view/components/TopBar.java     |  28 ++---
 3 files changed, 127 insertions(+), 66 deletions(-)

diff --git a/src/main/java/edu/ntnu/idatt2003/controller/ChaosGameController.java b/src/main/java/edu/ntnu/idatt2003/controller/ChaosGameController.java
index a67f353..4c7a04a 100644
--- a/src/main/java/edu/ntnu/idatt2003/controller/ChaosGameController.java
+++ b/src/main/java/edu/ntnu/idatt2003/controller/ChaosGameController.java
@@ -1,8 +1,14 @@
 package edu.ntnu.idatt2003.controller;
 
-import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionFactoryException;
-import edu.ntnu.idatt2003.exceptions.ChaosGameException;
-import edu.ntnu.idatt2003.exceptions.ChaosGameFileHandlerException;
+import edu.ntnu.idatt2003.exceptions.CouldNotWriteException;
+import edu.ntnu.idatt2003.exceptions.EmptyListException;
+import edu.ntnu.idatt2003.exceptions.InvalidPositiveIntException;
+import edu.ntnu.idatt2003.exceptions.InvalidSignException;
+import edu.ntnu.idatt2003.exceptions.InvalidTypeException;
+import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException;
+import edu.ntnu.idatt2003.exceptions.IsNullException;
+import edu.ntnu.idatt2003.exceptions.ObservingException;
+import edu.ntnu.idatt2003.exceptions.WrongFileFormatException;
 import edu.ntnu.idatt2003.model.game.ChaosGame;
 import edu.ntnu.idatt2003.model.game.ChaosGameDescription;
 import edu.ntnu.idatt2003.model.game.ChaosGameDescriptionFactory;
@@ -12,6 +18,7 @@ import edu.ntnu.idatt2003.util.ExceptionLogger;
 import edu.ntnu.idatt2003.view.PopupHandler;
 import edu.ntnu.idatt2003.view.components.ViewCanvas;
 import java.io.File;
+import java.io.FileNotFoundException;
 import javafx.animation.KeyFrame;
 import javafx.animation.Timeline;
 import javafx.util.Duration;
@@ -20,15 +27,25 @@ import javafx.util.Duration;
  * The controller class for the chaos game.
  */
 public class ChaosGameController implements Observer {
+  //Constants for the chaos game.
   public static final int CHAOS_GAME_WIDTH = 680;
   public static final int CHAOS_GAME_HEIGHT = 680;
   public static final String START_DESCRIPTION = "Julia Set";
 
+  //Constants for the animation
+  public static int RUN_SECONDS = 3;
+  public static int FPS = 60;
+  public static double K = 0.05;
+
+  //Constant for unexpected exceptions not caused by the user
+  public static final String UNEXPECTED_EXCEPTION =
+      "Something went wrong. Please try again or restart.";
+
   private ChaosGame chaosGame = null;
   private Timeline timeline;
   private final ViewCanvas viewCanvas;
   private final PopupHandler popupHandler;
-  private ExceptionLogger exceptionLogger;
+  private final ExceptionLogger exceptionLogger;
 
   /**
    * Constructor for the ChaosGameController class.
@@ -36,15 +53,18 @@ public class ChaosGameController implements Observer {
    * @param viewCanvas the view canvas to draw on.
    */
   public ChaosGameController(ViewCanvas viewCanvas, PopupHandler popupHandler) {
+    exceptionLogger = new ExceptionLogger("ChaosGameController");
     this.viewCanvas = viewCanvas;
     this.popupHandler = popupHandler;
     try {
-      chaosGame = new ChaosGame(ChaosGameDescriptionFactory.get(START_DESCRIPTION), CHAOS_GAME_WIDTH, CHAOS_GAME_HEIGHT);
+      chaosGame = new ChaosGame(ChaosGameDescriptionFactory.get(
+          START_DESCRIPTION), CHAOS_GAME_WIDTH, CHAOS_GAME_HEIGHT);
       chaosGame.attach(this);
-    } catch (ChaosGameException | ChaosGameDescriptionFactoryException ex) {
-      popupHandler.showErrorPopup(ex.getMessage());
+    } catch (EmptyListException | InvalidVectorRangeException | InvalidSignException
+             | IsNullException | InvalidTypeException | InvalidPositiveIntException e) {
+      exceptionLogger.logSevere(e);
+      popupHandler.showErrorPopup(UNEXPECTED_EXCEPTION);
     }
-    exceptionLogger = new ExceptionLogger("ChaosGameController");
   }
 
   /**
@@ -58,8 +78,10 @@ public class ChaosGameController implements Observer {
       chaosGame.resetGameWithDescription(newDescription);
       stopTimeline();
       popupHandler.showSuccessPopup(description + " loaded successfully");
-    } catch (ChaosGameDescriptionFactoryException | ChaosGameException ex) {
-      popupHandler.showErrorPopup(ex.getMessage());
+    } catch (IsNullException | InvalidVectorRangeException | EmptyListException
+             | InvalidSignException | InvalidTypeException e) {
+      exceptionLogger.logSevere(e);
+      popupHandler.showErrorPopup(UNEXPECTED_EXCEPTION);
     }
   }
 
@@ -89,8 +111,16 @@ public class ChaosGameController implements Observer {
       ChaosGameDescription newDescription = fileHandler.readFromFile(file);
       chaosGame.resetGameWithDescription(newDescription);
       popupHandler.showSuccessPopup("File loaded successfully");
-    } catch (ChaosGameFileHandlerException | ChaosGameException ex) {
-      popupHandler.showErrorPopup(ex.getMessage());
+    } catch (IsNullException | InvalidVectorRangeException
+             | EmptyListException | InvalidSignException e) {
+      exceptionLogger.logSevere(e);
+      popupHandler.showErrorPopup(e.getMessage());
+    } catch (FileNotFoundException e) {
+      exceptionLogger.logWarning(e);
+      popupHandler.showErrorPopup("File not found");
+    } catch (WrongFileFormatException e) {
+      exceptionLogger.logWarning(e);
+      popupHandler.showErrorPopup(e.getMessage());
     }
   }
 
@@ -100,8 +130,9 @@ public class ChaosGameController implements Observer {
   public void runSteps(int steps) {
     try {
       chaosGame.runSteps(steps);
-    } catch (ChaosGameException ex) {
-      popupHandler.showErrorPopup(ex.getMessage());
+    } catch (InvalidPositiveIntException e) {
+      exceptionLogger.logWarning(e);
+      popupHandler.showErrorPopup(e.getMessage());
     }
   }
 
@@ -155,39 +186,43 @@ public class ChaosGameController implements Observer {
    */
   public void animateIterations(int iterations)  {
     if (iterations <= 0) {
-      popupHandler.showErrorPopup("Iterations must be a positive number");
+      try {
+        throw new InvalidPositiveIntException("Iterations must be a positive number");
+      } catch (InvalidPositiveIntException e) {
+        exceptionLogger.logWarning(e);
+        popupHandler.showErrorPopup(e.getMessage());
+      }
       return;
     }
-    int runSeconds = 3;
-    int fps = 60;
 
     final int [] x = {0};
-    double k = 0.05;
 
     final int [] totalSteps = {0};
     timeline = new Timeline();
-    KeyFrame keyFrame = new KeyFrame(Duration.millis(1000.0 / fps), e -> {
-      int steps = (int) (iterations * k / Math.exp(fps * runSeconds * k) * Math.exp(k * x[0]));
+    KeyFrame keyFrame = new KeyFrame(Duration.millis(1000.0 / FPS), e -> {
+      int steps = (int) (iterations * K / Math.exp(FPS * RUN_SECONDS * K) * Math.exp(K * x[0]));
       try {
         if (steps != 0) {
           chaosGame.runSteps(steps);
         }
-      } catch (ChaosGameException ex) {
-        popupHandler.showErrorPopup(ex.getMessage());
+      } catch (InvalidPositiveIntException ex) {
+        exceptionLogger.logSevere(ex);
+        popupHandler.showErrorPopup(UNEXPECTED_EXCEPTION);
         timeline.stop();
       }
       x[0]++;
       totalSteps[0] += steps;
     });
     timeline.getKeyFrames().add(keyFrame);
-    timeline.setCycleCount(fps * runSeconds);
+    timeline.setCycleCount(FPS * RUN_SECONDS);
     timeline.setOnFinished(e -> {
       try {
         if (iterations - totalSteps[0] != 0) {
           chaosGame.runSteps(iterations - totalSteps[0]);
         }
-      } catch (ChaosGameException ex) {
-        popupHandler.showErrorPopup(ex.getMessage());
+      } catch (InvalidPositiveIntException ex) {
+        exceptionLogger.logSevere(ex);
+        popupHandler.showErrorPopup(UNEXPECTED_EXCEPTION);
       }
     });
     timeline.play();
@@ -227,8 +262,9 @@ public class ChaosGameController implements Observer {
     try {
       fileHandler.writeToFile(chaosGame.getDescriptions(), file);
       popupHandler.showSuccessPopup("File written successfully");
-    } catch (ChaosGameFileHandlerException ex) {
-      popupHandler.showErrorPopup(ex.getMessage());
+    } catch (CouldNotWriteException e) {
+      exceptionLogger.logSevere(e);
+      popupHandler.showErrorPopup(UNEXPECTED_EXCEPTION);
     }
   }
 
@@ -236,6 +272,13 @@ public class ChaosGameController implements Observer {
     return popupHandler;
   }
 
+  /**
+   * logs a warning exception.
+   */
+  public void logWarning(Exception e) {
+    exceptionLogger.logWarning(e);
+  }
+
   /**
    * When the chaosGame is updated, this method is called.
   */
@@ -245,6 +288,14 @@ public class ChaosGameController implements Observer {
       case "clearGame" -> viewCanvas.reset();
       case "putPixel" -> drawCurrentPixel();
       case "setDescription" -> System.out.println("description");
+      default -> {
+        try {
+          throw new ObservingException(updated + " is not being observed.");
+        } catch (ObservingException e) {
+          exceptionLogger.logSevere(e);
+          popupHandler.showErrorPopup(UNEXPECTED_EXCEPTION);
+        }
+      }
     }
   }
 }
diff --git a/src/main/java/edu/ntnu/idatt2003/view/CommandLineInterface.java b/src/main/java/edu/ntnu/idatt2003/view/CommandLineInterface.java
index c0fb3fa..3289642 100644
--- a/src/main/java/edu/ntnu/idatt2003/view/CommandLineInterface.java
+++ b/src/main/java/edu/ntnu/idatt2003/view/CommandLineInterface.java
@@ -1,14 +1,19 @@
 package edu.ntnu.idatt2003.view;
 
-import edu.ntnu.idatt2003.exceptions.ChaosCanvasException;
-import edu.ntnu.idatt2003.exceptions.ChaosGameDescriptionException;
-import edu.ntnu.idatt2003.exceptions.ChaosGameException;
-import edu.ntnu.idatt2003.exceptions.ChaosGameFileHandlerException;
+import edu.ntnu.idatt2003.exceptions.CouldNotWriteException;
+import edu.ntnu.idatt2003.exceptions.EmptyListException;
+import edu.ntnu.idatt2003.exceptions.InvalidPositiveIntException;
+import edu.ntnu.idatt2003.exceptions.InvalidSignException;
+import edu.ntnu.idatt2003.exceptions.InvalidVectorRangeException;
+import edu.ntnu.idatt2003.exceptions.IsNullException;
 import edu.ntnu.idatt2003.exceptions.WrongFileFormatException;
 import edu.ntnu.idatt2003.model.game.ChaosGame;
 import edu.ntnu.idatt2003.model.game.ChaosGameDescription;
 import edu.ntnu.idatt2003.model.io.ChaosGameFileHandler;
 import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.List;
 import java.util.Scanner;
 
 /**
@@ -31,11 +36,8 @@ public class CommandLineInterface {
 
   /**
    * Starts the command line interface.
-   *
-   * @throws ChaosGameFileHandlerException if an error occurs while reading or writing to a file.
-   * @throws ChaosGameException if an error occurs while running the chaos game.
    */
-  public void start() throws ChaosGameFileHandlerException, ChaosGameException {
+  public void start() {
     boolean exit = false;
     while (!exit) {
       System.out.println("Welcome to the Chaos Game!");
@@ -59,14 +61,18 @@ public class CommandLineInterface {
 
   /**
    * Chooses a file to construct a ChaosGameDescription from.
-   *
-   * @throws ChaosGameFileHandlerException if an error occurs while getting the list of files
-   *      or reading from a file.
    */
-  private void chooseFile() throws ChaosGameFileHandlerException {
+  private void chooseFile() {
     System.out.println("Choose a file:");
     int i = 1;
-    for (String path : chaosGameFileHandler.listFiles()) {
+    List<String> files;
+    try {
+      files = chaosGameFileHandler.listFiles();
+    } catch (IOException e) {
+      System.out.println("An error occurred. Please try again.");
+      return;
+    }
+    for (String path : files) {
       String name = path.replace("src/main/resources/", "").replace(".txt", "");
       System.out.println(i + ". " + name);
       i++;
@@ -74,7 +80,7 @@ public class CommandLineInterface {
     int choice = scanner.nextInt();
     scanner.nextLine();
     boolean found = false;
-    for (String path : chaosGameFileHandler.listFiles()) {
+    for (String path : files) {
       choice--;
       if (choice == 0) {
         found = true;
@@ -84,8 +90,11 @@ public class CommandLineInterface {
           System.out.println("File read successfully!");
         } catch (WrongFileFormatException e) {
           System.out.println("Wrong file format. Please try again.");
-        } catch (ChaosGameFileHandlerException e) {
+        } catch (FileNotFoundException e) {
           System.out.println("File not found. Please try again.");
+        } catch (IsNullException | EmptyListException
+                 | InvalidVectorRangeException | InvalidSignException e) {
+          System.out.println("An error occurred. Please try again.");
         }
         break;
       }
@@ -109,21 +118,30 @@ public class CommandLineInterface {
       File file = new File(path);
       chaosGameFileHandler.writeToFile(description, file);
       System.out.println("File written successfully!");
-    } catch (ChaosGameFileHandlerException e) {
+    } catch (CouldNotWriteException e) {
       System.out.println("An error occurred. Please try again.");
     }
   }
 
   /**
    * Runs the chaos game and prints the result.
-   *
-   * @throws ChaosGameException if an error occurs while running the chaos game.
    */
-  private void runChaosGame() throws ChaosGameException {
-    ChaosGame chaosGame = new ChaosGame(description, width, height);
+  private void runChaosGame() {
+    ChaosGame chaosGame;
+    try {
+      chaosGame = new ChaosGame(description, width, height);
+    } catch (IsNullException | InvalidPositiveIntException | InvalidVectorRangeException e) {
+      System.out.println("An error occurred. Please try again.");
+      return;
+    }
     System.out.println("Choose number of steps:");
     int steps = scanner.nextInt();
-    chaosGame.runSteps(steps);
+    try {
+      chaosGame.runSteps(steps);
+    } catch (InvalidPositiveIntException e) {
+      System.out.println("Steps must be a positive number.");
+      return;
+    }
 
     StringBuilder sb = new StringBuilder();
     for (int i = 0; i < height; i++) {
diff --git a/src/main/java/edu/ntnu/idatt2003/view/components/TopBar.java b/src/main/java/edu/ntnu/idatt2003/view/components/TopBar.java
index 333f738..db93e12 100644
--- a/src/main/java/edu/ntnu/idatt2003/view/components/TopBar.java
+++ b/src/main/java/edu/ntnu/idatt2003/view/components/TopBar.java
@@ -1,12 +1,10 @@
 package edu.ntnu.idatt2003.view.components;
 
 import edu.ntnu.idatt2003.controller.ChaosGameController;
-import java.io.File;
-
 import edu.ntnu.idatt2003.view.components.Input.InputBar;
 import edu.ntnu.idatt2003.view.components.buttons.PrimaryButton;
 import edu.ntnu.idatt2003.view.components.buttons.SecondaryButton;
-import edu.ntnu.idatt2003.view.components.popups.EditPopup;
+import java.io.File;
 import javafx.geometry.Pos;
 import javafx.scene.control.Button;
 import javafx.scene.control.TextField;
@@ -22,7 +20,6 @@ import javafx.stage.Window;
 public class TopBar extends StackPane {
   private final ChaosGameController controller;
   private int iterations;
-  private EditPopup editPopup;
   private Window ownerWindow;
 
   /**
@@ -46,19 +43,13 @@ public class TopBar extends StackPane {
 
 
     Button juliaButton = new SecondaryButton("Julia Set");
-    juliaButton.setOnAction(e -> {
-      this.controller.resetChaosGameWithDescription("Julia Set");
-    });
+    juliaButton.setOnAction(e -> this.controller.resetChaosGameWithDescription("Julia Set"));
 
     Button sierpinskiButton = new SecondaryButton("Sierpinski");
-    sierpinskiButton.setOnAction(e -> {
-      this.controller.resetChaosGameWithDescription("Sierpinski");
-    });
+    sierpinskiButton.setOnAction(e -> this.controller.resetChaosGameWithDescription("Sierpinski"));
 
     Button barnsleyButton = new SecondaryButton("Barnsley");
-    barnsleyButton.setOnAction(e -> {
-      this.controller.resetChaosGameWithDescription("Barnsley");
-    });
+    barnsleyButton.setOnAction(e -> this.controller.resetChaosGameWithDescription("Barnsley"));
 
     Button readFileButton = new SecondaryButton("Read File");
     readFileButton.setOnAction(e -> {
@@ -72,7 +63,8 @@ public class TopBar extends StackPane {
     Button writeFileButton = new PrimaryButton("Write File");
     writeFileButton.setOnAction(e -> {
       FileChooser fileChooser = new FileChooser();
-      FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("TXT files (*.txt)", "*.txt");
+      FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter(
+          "TXT files (*.txt)", "*.txt");
       fileChooser.getExtensionFilters().add(extFilter);
       File file = fileChooser.showSaveDialog(ownerWindow);
       if (file != null) {
@@ -81,9 +73,7 @@ public class TopBar extends StackPane {
     });
 
     Button editButton = new PrimaryButton("Edit");
-    editButton.setOnAction(e -> {
-      this.controller.getPopupHandler().showEditPopup();
-    });
+    editButton.setOnAction(e -> this.controller.getPopupHandler().showEditPopup());
 
     TextField iterationsField = new InputBar();
     iterationsField.setPromptText("Iterations");
@@ -95,6 +85,7 @@ public class TopBar extends StackPane {
       try {
         iterations = Integer.parseInt(iterationsField.getText());
       } catch (NumberFormatException ex) {
+        controller.logWarning(ex);
         this.controller.getPopupHandler().showErrorPopup("Iterations must be a number");
         return;
       }
@@ -106,7 +97,8 @@ public class TopBar extends StackPane {
     HBox rightButtonBox = new HBox();
 
     leftButtonBox.getChildren().addAll(writeFileButton, editButton);
-    middleButtonBox.getChildren().addAll(juliaButton, sierpinskiButton, barnsleyButton, readFileButton);
+    middleButtonBox.getChildren().addAll(
+        juliaButton, sierpinskiButton, barnsleyButton, readFileButton);
     rightButtonBox.getChildren().addAll(iterationsField, runButton);
 
     leftButtonBox.setSpacing(8);
-- 
GitLab