Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to track exceptions in background job?

426 views
Skip to first unread message

Jens Weiermann

unread,
Jan 11, 2010, 11:15:49 AM1/11/10
to
Hi,

I'm downloading some files using System.Net.WebClient in a background
job like this:

$url = "SomeUrl";
$file = "SomeFile";

$job = start-job
-scriptblock {
param($url, $file)
$clnt = new-object System.Net.WebClient
$clnt.DownloadFile($url, $file)
}
-ArgumentList $url, $file

while($job.state -eq "Running")
{
# display some spinner
}
if ($job.state -eq "Completed")
{
write-host "Done!"
}
else
{
write-host "Error"
}

Now I need to know if the file has been successfully downloaded. The
WebClient will throw an exception if it hasn't, but I don't know how to
get hold of this exception ($job.state will be "completed" in both cases
now, so the "else" part above will never execute).

What am I missing?

Thanks!

Marco Shaw [MVP]

unread,
Jan 11, 2010, 11:53:44 AM1/11/10
to

If I follow what you ultimately want, check this:

PS > get-job

Id Name State HasMoreData Location
Command
-- ---- ----- ----------- --------
-------
1 Job1 Failed False localhost
foo
3 Job3 Completed True localhost
...


PS > receive-job -keep 3
Exception calling "DownloadFile" with "2" argument(s): "Value cannot be
null.
Parameter name: address"
+ CategoryInfo : NotSpecified: (:) [],
MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException

If I use Receive-Job to get the output of the job, I see an exception.

Does that help?

Marco

"Jens Weiermann" <j.wei...@wilms.com> wrote in message
news:#hkZYltk...@TK2MSFTNGP02.phx.gbl...

Cosmin Ilie

unread,
Jan 12, 2010, 1:59:01 AM1/12/10
to

I also posted this on powershellcommunity.org and Shay Levy
(http://blogs.microsoft.co.il/blogs/ScriptFanatic ) was kind anough to help
me. His solution was:

$KeepJob = $false
$job = Invoke-Command -computer computer1 { Get-Process} -AsJob
Register-ObjectEvent $job -EventName StateChanged -SourceIdentifier JobEnd
-Action {
if($job.State -eq "Completed")
{
Write-Host "$(Receive-Job $job -Keep:$KeepJob | Out-String)"
Unregister-Event -SourceIdentifier JobEnd }
}

"Marco Shaw [MVP]" wrote:

> If I follow what you ultimately want, check this:
>
> PS > get-job
>
> Id Name State HasMoreData Location
> Command
> -- ---- ----- ----------- --------
> -------
> 1 Job1 Failed False localhost
> foo
> 3 Job3 Completed True localhost

> ....

> .
>

Cosmin Ilie

unread,
Jan 12, 2010, 2:01:01 AM1/12/10
to
Sorry wrong thread.

Jens Weiermann

unread,
Jan 12, 2010, 3:05:48 AM1/12/10
to
Hi Marco,

Marco Shaw [MVP] schrieb:


> If I follow what you ultimately want, check this:

> [...]


> PS > receive-job -keep 3
> Exception calling "DownloadFile" with "2" argument(s): "Value cannot
> be null.
> Parameter name: address"
> + CategoryInfo : NotSpecified: (:) [],
> MethodInvocationException
> + FullyQualifiedErrorId : DotNetMethodException
>
> If I use Receive-Job to get the output of the job, I see an exception.
>
> Does that help?

thanks that works... but:

I was under the impression (maybe just wishful thinking?) that if an
(unhandled) exception would occur in the background job, the job would
enter the "Failed" state and JobStateInfo.Reason would be the exception.
I think that would be quite intuitive, but this obviously isn't the case.

Now, when does the job enter the "Failed" state? Does this happen at all?

Jens Weiermann

unread,
Jan 12, 2010, 3:27:07 AM1/12/10
to
Ok, found out that setting $erroractionpreference to "Stop" DOES put the
job into "Failed" state. Note that this has to be done INSIDE the script
block of the background job.

But the JobStateInfo.Reason is still empty. Maybe there's another
"magic" $errorsomething variable that will do this?

Jens Weiermann schrieb:

Jens Weiermann

unread,
Jan 12, 2010, 7:05:13 AM1/12/10
to
Hi again (and sorry for repeatedly answering my own posts ;-)

Jens Weiermann schrieb:


> Ok, found out that setting $erroractionpreference to "Stop" DOES put
> the job into "Failed" state. Note that this has to be done INSIDE the
> script block of the background job.
>
> But the JobStateInfo.Reason is still empty. Maybe there's another
> "magic" $errorsomething variable that will do this?

Got it working now. Turned out that I had to use
$job.ChildJobs[0].JobStateInfo instead of $job.JobStateInfo.

Can you explain this? The docs are not very detailed here...

So my code looks like this:

$job = start-job
-scriptblock {
param($url, $file)

$erroractionpreference = "Stop"


$clnt = new-object System.Net.WebClient
$clnt.DownloadFile($url, $file)
}
-ArgumentList $url, $file

while($job.state -eq "Running")
{
# let the user know something is being done
}

if ($job.state -eq "Completed")
{
write-host "Done!"
}

elseif ($job.state -eq "Failed")
{
write-error $job.childjobs[0].JobStateInfo.Reason.Message
}

Marco Shaw [MVP]

unread,
Jan 12, 2010, 10:59:20 AM1/12/10
to
> Can you explain this? The docs are not very detailed here...

Can I explain it? Nope... I didn't write the code. ;-)

Suggestions can be posted here:
https://connect.microsoft.com/powershell

Marco

Jens Weiermann

unread,
Jan 12, 2010, 11:14:28 AM1/12/10
to

Marco Shaw [MVP] schrieb:

>> Can you explain this? The docs are not very detailed here...
>
> Can I explain it? Nope... I didn't write the code. ;-)

I mean, what are childjobs anyway? Someone must have had a reason to do
it this way, but if they decide to go such a counter-intuitive way, then
they should at least document it! Here's what get-help about-jobs says
under the "INVESTIGATING A FAILED JOB" subject:

"To find out why a job failed, use the Reason subproperty of the job
object."

Well, this is obviously WRONG. In the then following example, they ARE
using $job.ChildJobs[0], but don't say a) why and b) that this is the
only way to go...


0 new messages