# Catching and redirecting STDERR output

**URL:** <https://www.ruby-forum.com/t/catching-and-redirecting-stderr-output/113787>\
**Category:** Ruby\
**Created:** [September 4, 2007, 11:41pm UTC](https://www.ruby-forum.com/t/catching-and-redirecting-stderr-output/113787 "2007-09-04T23:41:40Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![igotimac](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/85f322/32.png) [@igotimac](https://www.ruby-forum.com/u/igotimac)\
**Post date:** [September 4, 2007, 11:41pm UTC](https://www.ruby-forum.com/t/catching-and-redirecting-stderr-output/113787/1 "2007-09-04T23:41:40Z")

</div>

So ruby has this libxml that writes validation errors directly to  
standard  
error. The only way I’ve been able to figure out how to capture this  
output  
and then use it programmatically (send to logger and/or display to the  
user)  
is to do something like this:

require ‘xml/libxml’  
require ‘tempfile’

def capture\_stderr()  
begin  
err\_file = Tempfile.new(“err\_file”)  
err\_file.close  
old\_stderr = STDERR.dup  
STDERR.reopen(err\_file.path)  
STDERR.sync = true  
result = yield  
STDERR.flush  
err\_file.open  
err\_file.seek(0)  
err\_text = err\_file.read  
err\_file.close  
err\_file.unlink  
return result, err\_text  
ensure  
STDERR.reopen(old\_stderr)  
end  
end

And then I can call what I want to call like this:

result, errors = capture\_stderr{ …do something with XML::Document and  
XML::Dtd here… }

I’ve previously tried:  
Altering $stderr variable or overriding the IO class to overrride the  
puts  
or write methods, or re-opening STDERR to a StringIO.  
I figure none of these work because the STDERR call I want to intercept  
is  
actually in the C code that implements libxml as an fprintf  
So no extent of ruby object space manipulation is going to change that.

Can anybody see any danger of breakage here? Or perhaps have some other  
ideas on how to do this?
