aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib
diff options
context:
space:
mode:
authorHans Bolinder <[email protected]>2018-06-26 15:05:00 +0200
committerHans Bolinder <[email protected]>2018-08-20 14:05:56 +0200
commita00f10d6e65f64d3b47e7c32e82c6ccf611d46ff (patch)
tree09613d6e210d4873d4d4bbe0e788cf8732d13094 /lib/stdlib
parent4197110f6811de1677f167e6ffd4efc54c807f0c (diff)
downloadotp-a00f10d6e65f64d3b47e7c32e82c6ccf611d46ff.tar.gz
otp-a00f10d6e65f64d3b47e7c32e82c6ccf611d46ff.tar.bz2
otp-a00f10d6e65f64d3b47e7c32e82c6ccf611d46ff.zip
stdlib: Improve error handling in module io_lib
Diffstat (limited to 'lib/stdlib')
-rw-r--r--lib/stdlib/src/io_lib.erl49
-rw-r--r--lib/stdlib/test/io_SUITE.erl12
2 files changed, 46 insertions, 15 deletions
diff --git a/lib/stdlib/src/io_lib.erl b/lib/stdlib/src/io_lib.erl
index 3a5aba60b4..8223a52873 100644
--- a/lib/stdlib/src/io_lib.erl
+++ b/lib/stdlib/src/io_lib.erl
@@ -178,11 +178,11 @@ fread(Cont, Chars, Format) ->
Data :: [term()].
format(Format, Args) ->
- case catch io_lib_format:fwrite(Format, Args) of
- {'EXIT',_} ->
- erlang:error(badarg, [Format, Args]);
- Other ->
- Other
+ try io_lib_format:fwrite(Format, Args)
+ catch
+ C:R:S ->
+ test_modules_loaded(C, R, S),
+ erlang:error(badarg, [Format, Args])
end.
-spec format(Format, Data, Options) -> chars() when
@@ -193,11 +193,11 @@ format(Format, Args) ->
CharsLimit :: chars_limit().
format(Format, Args, Options) ->
- case catch io_lib_format:fwrite(Format, Args, Options) of
- {'EXIT',_} ->
- erlang:error(badarg, [Format, Args, Options]);
- Other ->
- Other
+ try io_lib_format:fwrite(Format, Args, Options)
+ catch
+ C:R:S ->
+ test_modules_loaded(C, R, S),
+ erlang:error(badarg, [Format, Args])
end.
-spec scan_format(Format, Data) -> FormatList when
@@ -208,7 +208,9 @@ format(Format, Args, Options) ->
scan_format(Format, Args) ->
try io_lib_format:scan(Format, Args)
catch
- _:_ -> erlang:error(badarg, [Format, Args])
+ C:R:S ->
+ test_modules_loaded(C, R, S),
+ erlang:error(badarg, [Format, Args])
end.
-spec unscan_format(FormatList) -> {Format, Data} when
@@ -223,7 +225,12 @@ unscan_format(FormatList) ->
FormatList :: [char() | format_spec()].
build_text(FormatList) ->
- io_lib_format:build(FormatList).
+ try io_lib_format:build(FormatList)
+ catch
+ C:R:S ->
+ test_modules_loaded(C, R, S),
+ erlang:error(badarg, [FormatList])
+ end.
-spec build_text(FormatList, Options) -> chars() when
FormatList :: [char() | format_spec()],
@@ -232,7 +239,23 @@ build_text(FormatList) ->
CharsLimit :: chars_limit().
build_text(FormatList, Options) ->
- io_lib_format:build(FormatList, Options).
+ try io_lib_format:build(FormatList, Options)
+ catch
+ C:R:S ->
+ test_modules_loaded(C, R, S),
+ erlang:error(badarg, [FormatList, Options])
+ end.
+
+%% Failure to load a module must not be labeled as badarg.
+%% C, R, and S are included so that the original error, which could be
+%% a bug in io_lib_format, can be found by tracing on
+%% test_modules_loaded/3.
+test_modules_loaded(_C, _R, _S) ->
+ Modules = [io_lib_format, io_lib_pretty, string, unicode],
+ case code:ensure_modules_loaded(Modules) of
+ ok -> ok;
+ Error -> erlang:error(Error)
+ end.
-spec print(Term) -> chars() when
Term :: term().
diff --git a/lib/stdlib/test/io_SUITE.erl b/lib/stdlib/test/io_SUITE.erl
index 79cee54335..f097552e8c 100644
--- a/lib/stdlib/test/io_SUITE.erl
+++ b/lib/stdlib/test/io_SUITE.erl
@@ -31,7 +31,7 @@
otp_10836/1, io_lib_width_too_small/1,
io_with_huge_message_queue/1, format_string/1,
maps/1, coverage/1, otp_14178_unicode_atoms/1, otp_14175/1,
- otp_14285/1, limit_term/1, otp_14983/1, otp_15103/1,
+ otp_14285/1, limit_term/1, otp_14983/1, otp_15103/1, otp_15076/1,
otp_15159/1]).
-export([pretty/2, trf/3]).
@@ -64,7 +64,7 @@ all() ->
io_lib_print_binary_depth_one, otp_10302, otp_10755, otp_10836,
io_lib_width_too_small, io_with_huge_message_queue,
format_string, maps, coverage, otp_14178_unicode_atoms, otp_14175,
- otp_14285, limit_term, otp_14983, otp_15103, otp_15159].
+ otp_14285, limit_term, otp_14983, otp_15103, otp_15076, otp_15159].
%% Error cases for output.
error_1(Config) when is_list(Config) ->
@@ -2639,3 +2639,11 @@ otp_15159(_Config) ->
"[atom]" =
lists:flatten(io_lib:format("~p", [[atom]], [{chars_limit,5}])),
ok.
+
+otp_15076(_Config) ->
+ {'EXIT', {badarg, _}} = (catch io_lib:format("~c", [a])),
+ L = io_lib:scan_format("~c", [a]),
+ {"~c", [a]} = io_lib:unscan_format(L),
+ {'EXIT', {badarg, _}} = (catch io_lib:build_text(L)),
+ {'EXIT', {badarg, _}} = (catch io_lib:build_text(L, [])),
+ ok.