diff --git a/bin/efa b/bin/efa
index b7b61d41fcde7ff9f3b404a1d38c5b6dd9138c87..7cd3bbb18980e2a095ed06a3f84e31ef1c023c72 100755
--- a/bin/efa
+++ b/bin/efa
@@ -114,11 +114,11 @@ else {
 	);
 }
 
-$efa->parse();
+my $err = $efa->parse();
 
-
-$efa->check_ambiguous();
-$efa->check_no_connections();
+if ($err and $err->isa('WWW::Efa::Error')) {
+	die $err->as_string();
+}
 
 my @connections = $efa->connections();
 
diff --git a/lib/WWW/Efa.pm b/lib/WWW/Efa.pm
index 58d55bd457b2792381b372364d0e18888fcc15dd..1d593a421bae3825c0358c5d9b1c97a7715b509e 100644
--- a/lib/WWW/Efa.pm
+++ b/lib/WWW/Efa.pm
@@ -40,8 +40,10 @@ use 5.010;
 use base 'Exporter';
 
 use XML::LibXML;
-use WWW::Efa::Error::Setup;
+use WWW::Efa::Error::Ambiguous;
 use WWW::Efa::Error::Backend;
+use WWW::Efa::Error::NoData;
+use WWW::Efa::Error::Setup;
 use WWW::Mechanize;
 
 our @EXPORT_OK = ();
@@ -213,7 +215,7 @@ sub parse_initial {
 
 	my $con_part = 0;
 	my $con_no;
-	my $cons;
+	my $cons = [];
 
 	my $xp_td = XML::LibXML::XPathExpression->new('//table//table/tr/td');
 	my $xp_img = XML::LibXML::XPathExpression->new('./img');
@@ -253,14 +255,7 @@ sub parse_initial {
 		}
 	}
 
-	if (defined $con_no) {
-		return $cons;
-	}
-	else {
-		return WWW::Efa::Error::Backend->new(
-			'no data'
-		);
-	}
+	return $cons;
 }
 
 sub parse_pretty {
@@ -465,6 +460,7 @@ Parse the B<efa.vrr.de> reply
 
 sub parse {
 	my ($self) = @_;
+	my $err;
 
 	my $tree = XML::LibXML->load_html(
 		string => $self->{'html_reply'},
@@ -472,10 +468,28 @@ sub parse {
 
 	my $raw_cons = parse_initial($tree);
 
+	if (@{$raw_cons} == 0) {
+		$self->{'error'} = WWW::Efa::Error::NoData->new();
+	}
+
 	for my $raw_con (@{$raw_cons}) {
 		push(@{$self->{'connections'}}, parse_pretty($raw_con));
 	}
 	$self->{'tree'} = $tree;
+
+	if ($err = $self->check_ambiguous()) {
+		$self->{'error'} = $err;
+		return $err;
+	}
+	elsif ($err = $self->check_no_connections()) {
+		$self->{'error'} = $err;
+		return $err;
+	}
+	elsif ($self->{'error'}) {
+		return $self->{'error'};
+	}
+
+	return $self->{'error'};
 }
 
 sub check_ambiguous {
@@ -487,15 +501,16 @@ sub check_ambiguous {
 
 	foreach my $select (@{$tree->findnodes($xp_select)}) {
 
-		my @possible = ($select->getAttribute('name'));
+		my $post_key = $select->getAttribute('name');
+		my @possible;
 
 		foreach my $val ($select->findnodes($xp_option)) {
 			push(@possible, $val->textContent());
 		}
 
-		return WWW::Efa::Error::Backend->new(
-			'ambiguous',
-			\@possible
+		return WWW::Efa::Error::Ambiguous->new(
+			$post_key,
+			@possible,
 		);
 	}
 }
@@ -511,7 +526,6 @@ sub check_no_connections {
 
 	if ($err_node) {
 		return WWW::Efa::Error::Backend->new(
-			'error',
 			$err_node->parentNode()->parentNode()->textContent()
 		);
 	}
diff --git a/lib/WWW/Efa/Error/Ambiguous.pm b/lib/WWW/Efa/Error/Ambiguous.pm
new file mode 100644
index 0000000000000000000000000000000000000000..e738a63d96c7d9e9887d6c45c332612efba26080
--- /dev/null
+++ b/lib/WWW/Efa/Error/Ambiguous.pm
@@ -0,0 +1,69 @@
+package WWW::Efa::Error::Ambiguous;
+
+=head1 NAME
+
+WWW::Efa::Error::Ambiguous - WWW::Efa error, ambiguous to/from/via input
+
+=head1 SYNOPSIS
+
+    use WWW::Efa::Error::Ambiguous;
+
+    my $error = WWW::Efa::Error::Ambiguous->new(
+        'name_origin', 'Bredeney', 'Bredeney Friedhof'
+    );
+
+    die $error->as_string();
+    # WWW::Efa error: ambiguous input for name_origin:
+    #     Bredeney
+    #     Bredeney Friedhof
+
+=head1 DESCRIPTION
+
+Class for all WWW::Efa-internal errors occuring during initialization. Usually
+caused by missing or invalid setup arguments.
+
+=cut
+
+use strict;
+use warnings;
+use 5.010;
+
+use base 'Exporter';
+
+our @EXPORT_OK = qw{};
+our @ISA = ('WWW::Efa::Error');
+
+sub new {
+	my ($obj, $key, @possible) = @_;
+	my $ref = {};
+
+	$ref->{'key'}      = $key;
+	$ref->{'possible'} = \@possible;
+
+	return bless($ref, $obj);
+}
+
+=head1 METHODS
+
+=head2 $error->as_string()
+
+Return the error as string, can directly be displayed to the user
+
+=cut
+
+sub as_string {
+	my ($self) = @_;
+
+	my $ret = sprintf(
+		"WWW::Efa error: ambiguous input for %s:\n",
+		$self->{'key'},
+	);
+
+	foreach my $value (@{$self->{'possible'}}) {
+		$ret .= "\t$value\n";
+	}
+
+	return $ret;
+}
+
+1;
diff --git a/lib/WWW/Efa/Error/Backend.pm b/lib/WWW/Efa/Error/Backend.pm
index b6ffa75c97944c5d8ea13b101c2f73377f01716c..930fed5868007e15533192d1e8be9a9311eee89c 100644
--- a/lib/WWW/Efa/Error/Backend.pm
+++ b/lib/WWW/Efa/Error/Backend.pm
@@ -1,5 +1,27 @@
 package WWW::Efa::Error::Backend;
 
+=head1 NAME
+
+WWW::Efa::Error::Backend - WWW::Efa unknown error from efa.vrr.de
+
+=head1 SYNOPSIS
+
+    use WWW::Efa::Error::Backend;
+
+    my $error = WWW::Efa::Error::Backend->new(
+        'Yadda Yadda'
+    );
+
+    die $error->as_string();
+    # WWW::Efa error from efa.vrr.de:
+    # Yadda Yadda
+
+=head1 DESCRIPTION
+
+Received an unknown error from efa.vrr.de
+
+=cut
+
 use strict;
 use warnings;
 use 5.010;
@@ -7,42 +29,32 @@ use 5.010;
 use base 'Exporter';
 
 our @EXPORT_OK = qw{};
+our @ISA = ('WWW::Efa::Error');
 
 sub new {
-	my ($obj, $type, $data) = @_;
+	my ($obj, $msg) = @_;
 	my $ref = {};
 
-	$ref->{'type'}   = $type;
-	$ref->{'data'}   = $data;
+	$ref->{'message'} = $msg;
 
 	return bless($ref, $obj);
 }
 
+=head1 METHODS
+
+=head2 $error->as_string()
+
+Return the error as string, can directly be displayed to the user
+
+=cut
+
 sub as_string {
 	my ($self) = @_;
-	my $ret;
-
-	given ($self->{'type'}) {
-		when ('no data') {
-			$ret = "WWW::Efa: efa.vrr.de returned no data\n";
-		}
-		when ('ambiguous') {
-			$ret = sprintf(
-				"WWW::Efa: efa.vrr.de: Ambiguous input for %s:\n",
-				shift(@{$self->{'data'}}),
-			);
-			foreach my $possible (@{$self->{'data'}}) {
-				$ret .= "\t${possible}\n";
-			}
-		}
-		when ('error') {
-			$ret = sprintf(
-				"WWW::Efa: efa.vrr.de error:\n%s\n",
-				$self->{'data'},
-			);
-		}
-	}
-	return $ret;
+
+	return sprintf(
+		"WWW::Efa error from efa.vrr.de:\n%s\n",
+		$self->{'message'},
+	);
 }
 
 1;
diff --git a/lib/WWW/Efa/Error/NoData.pm b/lib/WWW/Efa/Error/NoData.pm
new file mode 100644
index 0000000000000000000000000000000000000000..e74d22035fdf0f31b888868e909a42fe3a4c1f8f
--- /dev/null
+++ b/lib/WWW/Efa/Error/NoData.pm
@@ -0,0 +1,50 @@
+package WWW::Efa::Error::NoData;
+
+=head1 NAME
+
+WWW::Efa::Error::NoData - WWW::Efa error, efa.vrr.de returned no data
+
+=head1 SYNOPSIS
+
+    use WWW::Efa::Error::Setup;
+
+    my $error = WWW::Efa::Error::NoData->new();
+
+    die $error->as_string();
+    # WWW::Efa error: No data returned by efa.vrr.de
+
+=head1 DESCRIPTION
+
+efa.vrr.de returned no parsable data
+
+=cut
+
+use strict;
+use warnings;
+use 5.010;
+
+use base 'Exporter';
+
+our @EXPORT_OK = qw{};
+our @ISA = ('WWW::Efa::Error');
+
+sub new {
+	my ($obj) = @_;
+	my $ref = {};
+
+	return bless($ref, $obj);
+}
+
+=head1 METHODS
+
+=head2 $error->as_string()
+
+Return the error as string, can directly be displayed to the user
+
+=cut
+
+sub as_string {
+	return "WWW::Efa error: No data returned by efa.vrr.de\n";
+}
+
+1;
diff --git a/lib/WWW/Efa/Error/Setup.pm b/lib/WWW/Efa/Error/Setup.pm
index 386613b7149e9da68cb64ba193a3a96423ae63e4..98406879c4528389d41c91a0d638b2f93651dabb 100644
--- a/lib/WWW/Efa/Error/Setup.pm
+++ b/lib/WWW/Efa/Error/Setup.pm
@@ -52,7 +52,6 @@ Return the error as string, can directly be displayed to the user
 
 sub as_string {
 	my ($self) = @_;
-	my $ret;
 
 	return sprintf(
 		"WWW::Efa setup error: Wrong arg for option %s: %s\n%s\n",
diff --git a/t/60-bin-efa.t b/t/60-bin-efa.t
index 8337b62cb1834043202466f994306798a575fb34..2b60233ad1c5b958f7e69692bbe2e8b5497262fd 100644
--- a/t/60-bin-efa.t
+++ b/t/60-bin-efa.t
@@ -3,7 +3,7 @@ use strict;
 use warnings;
 use 5.010;
 
-use Test::Command tests => 85;
+use Test::Command tests => 94;
 
 my $efa     = 'bin/efa';
 my $testarg = "E HBf MH HBf";
@@ -154,13 +154,11 @@ $cmd->exit_is_num(0);
 $cmd->stdout_is_file("t/out/e_hbf_mh_hbf.ignore_none");
 $cmd->stderr_is_eq($EMPTY);
 
-__END__
-
 $cmd = Test::Command->new(
 	cmd => "$efa $test_parse < t/in/ambiguous"
 );
 
-$cmd->exit_is_num(1);
+$cmd->exit_isnt_num(0);
 $cmd->stdout_is_eq($EMPTY);
 $cmd->stderr_is_file('t/out/ambiguous');
 
@@ -168,7 +166,7 @@ $cmd = Test::Command->new(
 	cmd => "$efa $test_parse < t/in/no_connections"
 );
 
-$cmd->exit_is_num(2);
+$cmd->exit_isnt_num(0);
 $cmd->stdout_is_eq($EMPTY);
 $cmd->stderr_is_file('t/out/no_connections');
 
@@ -176,6 +174,6 @@ $cmd = Test::Command->new(
 	cmd => "$efa $test_parse < t/in/invalid_input"
 );
 
-$cmd->exit_is_num(3);
+$cmd->exit_isnt_num(0);
 $cmd->stdout_is_eq($EMPTY);
 $cmd->stderr_is_file('t/out/invalid_input');
diff --git a/t/out/ambiguous b/t/out/ambiguous
index 0dd20432c375c8f679b6e0f0083ad530495a4983..787b3fdb5489faee3e431d8a759e74893c09b6e4 100644
--- a/t/out/ambiguous
+++ b/t/out/ambiguous
@@ -1,9 +1,4 @@
-Ambiguous input for name_origin
+WWW::Efa error: ambiguous input for name_origin:
 	Bredeney 
 	Bredeney Friedhof 
 	Bredeneyer Kreuz 
-Ambiguous input for name_destination
-	Werden Brücke 
-	Werden S 
-	Werdener Markt 
-	Werdener Str. 
diff --git a/t/out/invalid_input b/t/out/invalid_input
index 5686f5d558a1da5405b2e5447c66cd5dbd0ae366..2d22895b69b1cc9850f7cafb73cfab4fc9146748 100644
--- a/t/out/invalid_input
+++ b/t/out/invalid_input
@@ -1 +1 @@
-efa.vrr.de returned no connections, check your input data.
+WWW::Efa error: No data returned by efa.vrr.de
diff --git a/t/out/no_connections b/t/out/no_connections
index f464ad336db474098d59d553f9d4c1d2fd488950..f081ab70c5ec43544b8b4859e8dd8079884d7e65 100644
--- a/t/out/no_connections
+++ b/t/out/no_connections
@@ -1,5 +1,4 @@
-Looks like efa.vrr.de showed an error.
-I will now try to dump the error message:
+WWW::Efa error from efa.vrr.de:
 
 Leider konnte für Ihre Anfrage keine Verbindung gefunden werden! Bitte ändern Sie Ihre Eingabe (z.B. Fußwegezeit in den Mobilitätseinstellungen) oder starten Sie eine neue Anfrage!