Why doesn't Perl 6's try handle a non-zero exit in shell()? - exception

This try catches the exception:
try die X::AdHoc;
say "Got to the end";
The output shows that the program continues:
Got to the end
If I attempt it with shell and a command that doesn't exit with 0, the try doesn't catch it:
try shell('/usr/bin/false');
say "Got to the end";
The output doesn't look like an exception:
The spawned command '/usr/bin/false' exited unsuccessfully (exit code: 1)
in block <unit> at ... line ...
What's going on that this makes it through the try?

The answer is really provided by Jonathan Worthington:
https://irclog.perlgeek.de/perl6-dev/2017-04-04#i_14372945
In short, shell() returns a Proc object. The moment that object is sunk, it will throw the exception that it has internally if running the program failed.
$ 6 'dd shell("/usr/bin/false")'
Proc.new(in => IO::Pipe, out => IO::Pipe, err => IO::Pipe, exitcode => 1, signal => 0, command => ["/usr/bin/false"])
So, what you need to do is catch the Proc object in a variable, to prevent it from being sunk:
$ 6 'my $result = shell("/usr/bin/false"); say "Got to the end"'
Got to the end
And then you can use $result.exitcode to see whether it was successful or not.

Related

restoring the exception environment

Can anyone explain the concept of restoring the exception environment simply and smoothly.
It is said that when we use the exception handler in the try...endtry statement،When the program reaches the endtry, it restores the exception environment, but if it suddenly encounters a break command, for example, this recovery does not take place.
And the program even after exiting the try.......endtry command thinks that it is in the previous exception environment, and if another error occurs, it returns to the previous try......endtry command.
Like the following code snippet:
program testBadInput3;
#include( "stdlib.hhf" )
static
input: int32;
begin testBadInput3;
// This forever loop repeats
//until the user enters
// a good integer and the
break
//statement below
// exits the loop.
forever
try
stdout.put( "Enter an integer
value: " );
stdin.get( input );
stdout.put( "The first input
value was: ", input, nl );
break;
exception( ex.ValueOutOfRange
)
stdout.put( "The value was too
large, re-enter." nl );
exception( ex.ConversionError
)
stdout.put( "The input
contained illegal characters,
re-enter." nl );
endtry;
endfor;
// Note that the following
code //is outside the loop and
there
// is no try..endtry statement
//protecting this code.
stdout.put( "Enter another
number: " );
stdin.get( input );
stdout.put( "The new number
is:
", input, nl );
end testBadInput3;

Python JSON Decoding With Asynchat Cannot Catch ValueError Exception

I can't seem to catch an exception when using json.loads even though I specifically call it out. I largely see this when trying to stress my server with lots of client connection sending data very quickly. See my error below:
(I've replaced my IP address with X's in the error code)
EX: Unterminated string starting at: line 1 column 49 (char 48) Data:
'{"ap-hdop":0.55,"rtcmin":"38","ap-latdec":3.134,"a' error: uncaptured
python exception, closing channel
(:Unterminated string
starting at: line 1 column 49 (char 48)
[//faraday_server_handler.py|collect_incoming_data|34]
[/usr/lib/python2.7/json/init.py|loads|338]
[/usr/lib/python2.7/json/decoder.py|decode|366]
[/usr/lib/python2.7/json/decoder.py|raw_decode|382])
I understand this that the code fails because I simply miss a double quotes on the line:
'{"ap-hdop":0.55,"rtcmin":"38","ap-latdec":3.134,"a'
This line is usually a LOT longer so that "a.... was supposed to keep going and complete it's quotes.
Here's my relevant code:
def collect_incoming_data(self, data):
"""Read an incoming message from the client, place JSON message data into buffer"""
#self.logger.debug('collect_fing_data() -> (%d bytes)\n"""%s"""', len(data), data)
try:
loaded_data = json.loads(data)
except ValueError, ex:
self.handle_error()
type,value,traceback = sys.exc_info()
print type
#print "Collect Incoming Data: " . time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime())
print "EX: ", ex
print "Data: ",repr(data)
Any ideas? I scoured the internet to see if I can find this issue, but I appear to be setting up to capture the exception which everyone else having this issue with loads seems to suggest to do.
EDIT 3/1/2016 - Evening
Commenting out my exception handle_error() let me see more of the error:
except ValueError, ex:
self.handle_error()
type,value,traceback = sys.exc_info()
print type
#print "Collect Incoming Data: " . time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime())
print "EX: ", ex
print "Data: ",repr(data)
Below is my new error, I've commented out personal data. It's apparent that the issue I really have now is in-fact the unterminated string
EX: Unterminated string starting at:
line 1 column 49 (char 48) Data:
'{"ap-hdop":0.55,"rtcmin":"31","ap-latdec":XX.XXX,"a' EX: No JSON object could be decoded Data:
'p-latdeg":34,"adc6":2006,"adc7":2007,"adc4":2004,"adc5":2005,"adc2":2002,"adc3":2003,"adc0":2000,"adc1":2001,"gpio-0":30,"gpio-1":50,"gpio-2":70,"speed":5.0,"adc8":2008,"rtcday":"01","longdeg":118,"longdec":XX.XXX,"altitude":31.0,"ap-speed":0.0,"ap-pdop":0.77,"lat-dir":"N","long-dir":"W","hdop":0.01,"ap-rf":0,"alt-units":"M","rtcdow":"2","callsign":"XXXXX","ap-callsign":"XXXXX","id":1,"ap-id":1,"rtcyear":"2016","rtcmon":"03","ap-vdop":0.66,"ap-lat-dir":"N","vdop":0.02,"rtchour":"22","latdec":XX.XXX,"latdeg":34,"ap-longdeg":118,"ap-longdec":XX.XXX,"rtcsec":"15","ap-altitude":86.0,"ap-long-dir":"W","pdop":0.01,"ap-alt-units":"M","faraday-port":0}'
OK my original question was answered which was "Why am I not catching the ValueError exception even though I am providing code to do just that?"
#tadhg McDonald-jensen was correct with his comment to remove my call to handle_error().
I still have some other issues but they are a different question. Thanks!

Parallel mysql I/O in Ruby

Good day to you. I'm writing a cron job that hopefully will split a huge MySQL table to several threads and do some work on them. This is the minimal sample of what I have at the moment:
require 'mysql'
require 'parallel'
#db = Mysql.real_connect("localhost", "root", "", "database")
#threads = 10
Parallel.map(1..#threads, :in_processes => 8) do |i|
begin
#db.query("SELECT url FROM pages LIMIT 1 OFFSET #{i}")
rescue Mysql::Error => e
#db.reconnect()
puts "Error code: #{e.errno}"
puts "Error message: #{e.error}"
puts "Error SQLSTATE: #{e.sqlstate}" if e.respond_to?("sqlstate")
end
end
#db.close
The threads don't need to return anything, they get their job share and they do it. Only they don't. Either connection to MySQL is lost during the query, or connection doesn't exist (MySQL server has gone away?!), or no _dump_data is defined for class Mysql::Result and then Parallel::DeadWorker.
How to do that right?
map method expects a result; I don't need a result, so I switched to each:
Parallel.each(1..#threads, :in_processes => 8) do |i|
Also this solves a problem with MySQL: I just needed to start the connection inside the parallel process. When using each loop, it's possible. Of course, connection should be closed inside the process also.

Error in fromJSON(paste(raw.data, collapse = "")) : unclosed string

I am using the R package rjson to download weather data from Wunderground.com. Often I leave the program to run and there are no problems, with the data being collected fine. However, often the program stops running and I get the following error message:
Error in fromJSON(paste(raw.data, collapse = "")) : unclosed string
In addition: Warning message:
In readLines(conn, n = -1L, ok = TRUE) :
incomplete final line found on 'http://api.wunderground.com/api/[my_API_code]/history_20121214pws:1/q/pws:IBIRMING7.json'
Does anyone know what this means, and how I can avoid it since it stops my program from collecting data as I would like?
Many thanks,
Ben
I can recreate your error message using the rjson package.
Here's an example that works.
rjson::fromJSON('{"x":"a string"}')
# $x
# [1] "a string"
If we omit a double quote from the value of x, then we get the error message.
rjson::fromJSON('{"x":"a string}')
# Error in rjson::fromJSON("{\"x\":\"a string}") : unclosed string
The RJSONIO package behaves slightly differently. Rather than throwing an error, it silently returns a NULL value.
RJSONIO::fromJSON('{"x":"a string}')
# $x
# NULL

If error messages echo line content

I try to capture lines with calculations in my text document
and execute them.
I use this in my function:
for i in range(startline,endline)
let calculation = getline(i)
...
let out = eval(calculation)
...
endfor
sometimes something goes wrong and I receive this message:
Error detected while processing function....
Line ...
E488: Trailing Characters
Line .. is the line-nr in my function.
I would like to know also which calculation it concerns (which line in my text doc):
If Error detected = echo calculation
How can I check if there is an error message and echo the variable "calculation"?
There are two ways to handle script errors inside a function:
The first is suppressing the error via :silent!. Two downsides: You have to manually check for success, and any normal output from the evaluated script is suppressed, too (unless you do contortions with :unsilent).
let v:errmsg = ''
silent! let out = eval(calculation)
if v:errmsg != ''
" error
endif
I would recommend the second way via try...catch, which avoids the issues with the output and having to explicitly check for an error:
try
let out = eval(calculation)
catch /^Vim\%((\a\+)\)\=:E/
" v:exception contains what is normally in v:errmsg, but with extra
" exception source info prepended, which we cut away.
let v:errmsg = printf("Line: %d\nCalculation: %s\nError: %s", i, calculation, substitute(v:exception, '^Vim\%((\a\+)\)\=:', '', ''))
echohl ErrorMsg
echomsg v:errmsg
echohl None
endtry