This looks like its a regression caused by localising $@.
Attached is a patch (with amended tests) that restores the throwing of a fatal error if load() generates an error and extension matching was used.
Cheers,
Russell.
From cfacf1cec779e9edb0bd24e8f2374e3f4cae1ca5 Mon Sep 17 00:00:00 2001
From: Russell Jenkins <veryrusty@gmail.com>
Date: Wed, 29 Apr 2015 10:48:45 +1000
Subject: [PATCH 1/2] Test load_files throws parse errors when use_ext=1
Piggyback off existing tests for invalid config files to verify a parse
error is thrown when the config is invalid and use_ext => 1.
---
t/50-general.t | 12 +++++++++++-
t/51-ini.t | 12 +++++++++++-
t/52-json.t | 12 +++++++++++-
t/53-perl.t | 13 +++++++++++--
t/54-xml.t | 13 ++++++++++++-
t/55-yaml.t | 12 +++++++++++-
6 files changed, 67 insertions(+), 7 deletions(-)
diff --git a/t/50-general.t b/t/50-general.t
index cc7d6f8..5361ca2 100644
--- a/t/50-general.t
+++ b/t/50-general.t
@@ -2,13 +2,14 @@ use strict;
use warnings;
use Test::More;
+use Config::Any;
use Config::Any::General;
if ( !Config::Any::General->is_supported ) {
plan skip_all => 'Config::General format not supported';
}
else {
- plan tests => 7;
+ plan tests => 9;
}
{
@@ -38,3 +39,12 @@ else {
ok( !$config, 'config load failed' );
ok( $@, "error thrown ($@)" );
}
+
+# parse error generated on invalid config
+{
+ my $file = 't/invalid/conf.conf';
+ my $config = eval { Config::Any->load_files( { files => [$file], use_ext => 1} ) };
+
+ ok( !$config, 'config load failed' );
+ ok( $@, "error thrown ($@)" );
+}
diff --git a/t/51-ini.t b/t/51-ini.t
index 1fea544..c85ab27 100644
--- a/t/51-ini.t
+++ b/t/51-ini.t
@@ -2,13 +2,14 @@ use strict;
use warnings;
use Test::More;
+use Config::Any;
use Config::Any::INI;
if ( !Config::Any::INI->is_supported ) {
plan skip_all => 'INI format not supported';
}
else {
- plan tests => 13;
+ plan tests => 15;
}
{
@@ -55,3 +56,12 @@ else {
ok( !$config, 'config load failed' );
ok( $@, "error thrown ($@)" );
}
+
+# parse error generated on invalid config
+{
+ my $file = 't/invalid/conf.ini';
+ my $config = eval { Config::Any->load_files( { files => [$file], use_ext => 1} ) };
+
+ ok( !$config, 'config load failed' );
+ ok( $@, "error thrown ($@)" );
+}
diff --git a/t/52-json.t b/t/52-json.t
index 65c6099..555e74e 100644
--- a/t/52-json.t
+++ b/t/52-json.t
@@ -2,13 +2,14 @@ use strict;
use warnings;
use Test::More;
+use Config::Any;
use Config::Any::JSON;
if ( !Config::Any::JSON->is_supported ) {
plan skip_all => 'JSON format not supported';
}
else {
- plan tests => 4;
+ plan tests => 6;
}
{
@@ -25,3 +26,12 @@ else {
ok( !$config, 'config load failed' );
ok( $@, "error thrown ($@)" );
}
+
+# parse error generated on invalid config
+{
+ my $file = 't/invalid/conf.json';
+ my $config = eval { Config::Any->load_files( { files => [$file], use_ext => 1} ) };
+
+ ok( !$config, 'config load failed' );
+ ok( $@, "error thrown ($@)" );
+}
diff --git a/t/53-perl.t b/t/53-perl.t
index 5ad0468..1a749a1 100644
--- a/t/53-perl.t
+++ b/t/53-perl.t
@@ -1,8 +1,8 @@
use strict;
use warnings;
-use Test::More tests => 5;
-
+use Test::More tests => 7;
+use Config::Any;
use Config::Any::Perl;
{
@@ -24,3 +24,12 @@ use Config::Any::Perl;
ok( !$config, 'config load failed' );
ok( $@, "error thrown ($@)" );
}
+
+# parse error generated on invalid config
+{
+ my $file = 't/invalid/conf.pl';
+ my $config = eval { Config::Any->load_files( { files => [$file], use_ext => 1} ) };
+
+ ok( !$config, 'config load failed' );
+ ok( $@, "error thrown ($@)" );
+}
diff --git a/t/54-xml.t b/t/54-xml.t
index 45fd66e..0d546cb 100644
--- a/t/54-xml.t
+++ b/t/54-xml.t
@@ -2,13 +2,14 @@ use strict;
use warnings;
use Test::More;
+use Config::Any;
use Config::Any::XML;
if ( !Config::Any::XML->is_supported ) {
plan skip_all => 'XML format not supported';
}
else {
- plan tests => 6;
+ plan tests => 8;
}
{
@@ -39,3 +40,13 @@ SKIP: {
ok( $config, 'config loaded' );
ok( !$@, 'no error thrown' );
}
+
+# parse error generated on invalid config
+{
+ my $file = 't/invalid/conf.xml';
+ my $config = eval { Config::Any->load_files( { files => [$file], use_ext => 1} ) };
+
+ ok( !$config, 'config load failed' );
+ ok( $@, "error thrown ($@)" );
+}
+
diff --git a/t/55-yaml.t b/t/55-yaml.t
index 7b7b5bc..b6d1f9e 100644
--- a/t/55-yaml.t
+++ b/t/55-yaml.t
@@ -3,13 +3,14 @@ use warnings;
no warnings 'once';
use Test::More;
+use Config::Any;
use Config::Any::YAML;
if ( !Config::Any::YAML->is_supported ) {
plan skip_all => 'YAML format not supported';
}
else {
- plan tests => 4;
+ plan tests => 6;
}
{
@@ -26,3 +27,12 @@ else {
ok( !$config, 'config load failed' );
ok( $@, "error thrown ($@)" );
}
+
+# parse error generated on invalid config
+{
+ my $file = 't/invalid/conf.yml';
+ my $config = eval { Config::Any->load_files( { files => [$file], use_ext => 1} ) };
+
+ ok( !$config, 'config load failed' );
+ ok( $@, "error thrown ($@)" );
+}
--
2.2.1
From 38bd1c62c47857ac18a0b698442e84e2d68e222e Mon Sep 17 00:00:00 2001
From: Russell Jenkins <veryrusty@gmail.com>
Date: Wed, 29 Apr 2015 10:49:14 +1000
Subject: [PATCH 2/2] Capture file load errors for later use.
Localizing $@ also implies that any load error wasn't available outside
of the do block. Instead of always returning 1, return $@ so any error
is captured. The error is then rethrown if use_ext is enabled.
---
lib/Config/Any.pm | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/lib/Config/Any.pm b/lib/Config/Any.pm
index 7bdf2a6..2c2bc41 100644
--- a/lib/Config/Any.pm
+++ b/lib/Config/Any.pm
@@ -195,15 +195,15 @@ sub _load {
next unless $loader->is_supported;
$supported = 1;
my @configs;
- my $ok = do {
+ my $err = do {
local $@;
@configs = eval { $loader->load( $filename, $loader_args{ $loader } ); };
- 1;
+ $@;
};
# fatal error if we used extension matching
- croak "Error parsing $filename: $@" if !$ok and $use_ext_lut;
- next if !$ok or !@configs;
+ croak "Error parsing $filename: $err" if $err and $use_ext_lut;
+ next if $err or !@configs;
# post-process config with a filter callback
if ( $args->{ filter } ) {
--
2.2.1