jaimeiniesta

jaimeiniesta

Hello, I’ve tried 2 libraries for parsing XML: sweet_xml and quinn, and both rely on the Erlang package xmerl.

They both work great, but when they encounter malformed XML, they error and exit like this:

iex(4)> Quinn.parse "<xml>"
** (exit) {:fatal, {:unexpected_end, {:file, :file_name_unknown}, {:line, 1}, {:col, 6}}}
16:21:51.714 [error] 4108- fatal: :unexpected_end
xmerl_scan.erl:4111: :xmerl_scan.fatal/2
xmerl_scan.erl:572: :xmerl_scan.scan_document/2
xmerl_scan.erl:288: :xmerl_scan.string/2
lib/xml_parser/xml_parser.ex:5: Quinn.XmlParser.parse/1

If I directly use :xmerl_scan.string/1 I get the same error:

iex(1)> :xmerl_scan.string '<xml>'
** (exit) {:fatal, {:unexpected_end, {:file, :file_name_unknown}, {:line, 1}, {:col, 6}}}
16:36:46.245 [error] 4108- fatal: :unexpected_end
xmerl_scan.erl:4111: :xmerl_scan.fatal/2
xmerl_scan.erl:572: :xmerl_scan.scan_document/2
xmerl_scan.erl:288: :xmerl_scan.string/2

Now, I want to make my app rescue from this error, but I’m not being able to do this. I’ve tried this but it doesn’t work:

iex(1)> try do
...(1)>   :xmerl_scan.string '<xml>'
...(1)> rescue
...(1)>   RuntimeError -> "Error!"
...(1)> end
** (exit) {:fatal, {:unexpected_end, {:file, :file_name_unknown}, {:line, 1}, {:col, 6}}}

iex(1)>
16:40:20.003 [error] 4108- fatal: :unexpected_end

I suppose that it’s because it’s not a RuntimeError I’m dealing with, because it’s not from Elixir, but Erlang. I can catch the exit, however.

How can I rescue from this error?

Thanks!

Marked As Solved

OvermindDL1

OvermindDL1

Easiest thing would be just to set a new group leader for its (yours? If run in the same process, I don’t know if it is or not) process.

It should be able to be done via:

f = get_empty_group_leader() # Implement this yourself as a supervised GenServer somewhere
:elixir.group_leader(f, self()) # Or instead of self() use whatever is the PID of the xmerl process

The part you need to implement yourself of get_empty_group_leader() just use a GenServer somewhere that implements the file streaming erlang protocol (see erlang docs), or have it basically ignore everything (I think you need to send :ok back or something on a few of them though).

Also Liked

OvermindDL1

OvermindDL1

It is not ‘raising’ an error, so rescue will not handle it. It is ‘throwing’ an :exit, so you need to catch it like:

iex> try do
...>   exit "I am exiting"
...> catch
...>   :exit, _ -> "not really"
...> end
"not really"

And that is the only way to handle an exit in that context (without looking at xmerl itself, if it is another process then trapping exits would work too).

EDIT: Or more accurately for your use case:

iex(2)> try do
...(2)>  :xmerl_scan.string '<xml>'
...(2)> catch
...(2)>  :exit, e -> {:nope, e}
...(2)> end
[error] 4108- fatal: :unexpected_end

{:nope,
 {:fatal,
  {:unexpected_end, {:file, :file_name_unknown}, {:line, 1}, {:col, 6}}}}
alecnmk

alecnmk

Greetings,

Actually there is event simpler solution(s).

  1. xmerl_scan has quiet ({quiet, Flag}) as one of the options. When set to true xmerl behaves and nothing get’s error-logged. Details are here: http://erlang.org/doc/man/xmerl_scan.html

  2. I was experiencing same issue with false error reporting as @jaimeiniesta. And that’s Elixir Logger capturing erlang’s standard_error and logs it with error level to configured Logger backends. See :handle_otp_reports config option of the Elixir.Logger

  3. Solution with wrapping xmerl parsing in a separate process and setting group leader to stub GenServer didn’t work for me. But good implementation example could be found in ExUnit Capture logs/io sources: https://github.com/elixir-lang/elixir/blob/master/lib/ex_unit/lib/ex_unit/capture_io.ex

Cheers

jaimeiniesta

jaimeiniesta OP

For the record, SweetXml allows passing options to xmerl when parsing:

SweetXml.parse(doc, quiet: true)

Where Next? Top

Trending in Questions Top

katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
achenet
Hello, I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind. However, when I launch mix phx.server, I get an error...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
Cxx-mlr
I’m working on a small exercise involving update_in/3, and I came up with this solution: data = %{ name: "Periodic Table", category:...
New
ChrisAmelia
I’ve got trouble wrapping my head around the order in which functions are called in this snippet (from Phoenix’s authentication): toke...
New
dillonoconnor
Is there any way to avoid the Hologram compiler running when using iex? It seems like the front-end code could potentially be disregarded...
New
thiagogsr
** (ArgumentError) expected :max_attempts to be a positive integer, got: {:@, [line: 10, column: 19], [{:max_attempts, [line: 10, column:...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews