Skip to content

Commit

Permalink
(maint) better error handling
Browse files Browse the repository at this point in the history
Add better error handling to some of the PowerShell files.
  • Loading branch information
ferventcoder committed Apr 24, 2016
1 parent 589515c commit 72934ba
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 112 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -149,13 +149,17 @@ param(
$headers = @{}
if ($url.StartsWith('http')) {
try {
$headers = Get-WebHeaders $url
$headers = Get-WebHeaders $url -ErrorAction "Stop"
} catch {
if ($host.Version -lt (new-object 'Version' 3,0)) {
Write-Debug "Converting Security Protocol to SSL3 only for Powershell v2"
# this should last for the entire duration
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Ssl3
$headers = Get-WebHeaders $url
try {
$headers = Get-WebHeaders $url -ErrorAction "Stop"
} catch {
Write-Host "Attempt to get headers for $url failed.`n $($_.Exception.Message)"
}
} else {
Write-Host "Attempt to get headers for $url failed.`n $($_.Exception.Message)"
}
Expand Down
21 changes: 14 additions & 7 deletions src/chocolatey.resources/helpers/functions/Get-FileName.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,6 @@ param(
$containsEquals = [System.IO.Path]::GetFileName($url).Contains('=')
$fileName = [System.IO.Path]::GetFileName($response.ResponseUri.ToString())
}

$response.Close()
$response.Dispose()

[System.Text.RegularExpressions.Regex]$containsABadCharacter = New-Object Regex("[" + [System.Text.RegularExpressions.Regex]::Escape([System.IO.Path]::GetInvalidFileNameChars()) + "]", [System.Text.RegularExpressions.RegexOptions]::IgnorePatternWhitespace);

Expand All @@ -141,12 +138,22 @@ param(
Write-Debug "File name determined from url is '$fileName'"

return $fileName
} catch
{
$request.ServicePoint.MaxIdleTime = 0
$request.Abort();
} catch {
if ($request -ne $null) {
$request.ServicePoint.MaxIdleTime = 0
$request.Abort();
# ruthlessly remove $request to ensure it isn't reused
Remove-Variable request
Start-Sleep 1
[GC]::Collect()
}

Write-Debug "Url request/response failed - file name will be '$originalFileName': $($_)"

return $originalFileName
} finally {
if ($response -ne $null) {
$response.Close();
}
}
}
207 changes: 114 additions & 93 deletions src/chocolatey.resources/helpers/functions/Get-WebFile.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -94,119 +94,140 @@ param(
}
}

$res = $req.GetResponse();
try {
[System.Net.HttpWebResponse]$res = $req.GetResponse();

try {
$headers = @{}
foreach ($key in $res.Headers) {
$value = $res.Headers[$key];
if ($value) {
$headers.Add("$key","$value")
try {
$headers = @{}
foreach ($key in $res.Headers) {
$value = $res.Headers[$key];
if ($value) {
$headers.Add("$key","$value")
}
}
}

if ($headers.ContainsKey("Content-Type")) {
$contentType = $headers['Content-Type']
if ($contentType -ne $null) {
if ($contentType.ToLower().Contains("text/html") -or $contentType.ToLower().Contains("text/plain")) {
Write-Warning "$fileName is of content type $contentType"
Set-Content -Path "$fileName.istext" -Value "$fileName has content type $contentType" -Encoding UTF8 -Force
if ($headers.ContainsKey("Content-Type")) {
$contentType = $headers['Content-Type']
if ($contentType -ne $null) {
if ($contentType.ToLower().Contains("text/html") -or $contentType.ToLower().Contains("text/plain")) {
Write-Warning "$fileName is of content type $contentType"
Set-Content -Path "$fileName.istext" -Value "$fileName has content type $contentType" -Encoding UTF8 -Force
}
}
}
} catch {
# not able to get content-type header
Write-Debug "Error getting content type - $($_.Exception.Message)"
}

if($fileName -and !(Split-Path $fileName)) {
$fileName = Join-Path (Get-Location -PSProvider "FileSystem") $fileName
}
elseif((!$Passthru -and ($fileName -eq $null)) -or (($fileName -ne $null) -and (Test-Path -PathType "Container" $fileName)))
{
[string]$fileName = ([regex]'(?i)filename=(.*)$').Match( $res.Headers["Content-Disposition"] ).Groups[1].Value
$fileName = $fileName.trim("\/""'")
if(!$fileName) {
$fileName = $res.ResponseUri.Segments[-1]
$fileName = $fileName.trim("\/")
if(!$fileName) {
$fileName = Read-Host "Please provide a file name"
}
$fileName = $fileName.trim("\/")
if(!([IO.FileInfo]$fileName).Extension) {
$fileName = $fileName + "." + $res.ContentType.Split(";")[0].Split("/")[1]
}
}
}
} catch {
# not able to get content-type header
Write-Debug "Error getting content type - $($_.Exception.Message)"
}
$fileName = Join-Path (Get-Location -PSProvider "FileSystem") $fileName
}
if($Passthru) {
$encoding = [System.Text.Encoding]::GetEncoding( $res.CharacterSet )
[string]$output = ""
}

if($fileName -and !(Split-Path $fileName)) {
$fileName = Join-Path (Get-Location -PSProvider "FileSystem") $fileName
}
elseif((!$Passthru -and ($fileName -eq $null)) -or (($fileName -ne $null) -and (Test-Path -PathType "Container" $fileName)))
{
[string]$fileName = ([regex]'(?i)filename=(.*)$').Match( $res.Headers["Content-Disposition"] ).Groups[1].Value
$fileName = $fileName.trim("\/""'")
if(!$fileName) {
$fileName = $res.ResponseUri.Segments[-1]
$fileName = $fileName.trim("\/")
if(!$fileName) {
$fileName = Read-Host "Please provide a file name"
}
$fileName = $fileName.trim("\/")
if(!([IO.FileInfo]$fileName).Extension) {
$fileName = $fileName + "." + $res.ContentType.Split(";")[0].Split("/")[1]
}
if($res.StatusCode -eq 401 -or $res.StatusCode -eq 403 -or $res.StatusCode -eq 404) {
$env:ChocolateyExitCode = $res.StatusCode
throw "Remote file either doesn't exist, is unauthorized, or is forbidden for '$url'."
}
$fileName = Join-Path (Get-Location -PSProvider "FileSystem") $fileName
}
if($Passthru) {
$encoding = [System.Text.Encoding]::GetEncoding( $res.CharacterSet )
[string]$output = ""
}

if($res.StatusCode -eq 200) {
[long]$goal = $res.ContentLength
$goalFormatted = Format-FileSize $goal
$reader = $res.GetResponseStream()
if($res.StatusCode -eq 200) {
[long]$goal = $res.ContentLength
$goalFormatted = Format-FileSize $goal
$reader = $res.GetResponseStream()

if ($fileName) {
$fileDirectory = $([System.IO.Path]::GetDirectoryName($fileName))
if (!(Test-Path($fileDirectory))) {
[System.IO.Directory]::CreateDirectory($fileDirectory) | Out-Null
}
if ($fileName) {
$fileDirectory = $([System.IO.Path]::GetDirectoryName($fileName))
if (!(Test-Path($fileDirectory))) {
[System.IO.Directory]::CreateDirectory($fileDirectory) | Out-Null
}

try {
$writer = new-object System.IO.FileStream $fileName, "Create"
} catch {
throw $_.Exception
try {
$writer = new-object System.IO.FileStream $fileName, "Create"
} catch {
throw $_.Exception
}
}
}

[byte[]]$buffer = new-object byte[] 1048576
[long]$total = [long]$count = [long]$iterLoop =0
[byte[]]$buffer = new-object byte[] 1048576
[long]$total = [long]$count = [long]$iterLoop =0

$originalEAP = $ErrorActionPreference
$ErrorActionPreference = 'Stop'
try {
do
{
$count = $reader.Read($buffer, 0, $buffer.Length);
if($fileName) {
$writer.Write($buffer, 0, $count);
}

if($Passthru){
$output += $encoding.GetString($buffer,0,$count)
} elseif(!$quiet) {
$total += $count
$totalFormatted = Format-FileSize $total
if($goal -gt 0 -and ++$iterLoop%10 -eq 0) {
Write-Progress "Downloading $url to $fileName" "Saving $totalFormatted of $goalFormatted ($total/$goal)" -id 0 -percentComplete (($total/$goal)*100)
$originalEAP = $ErrorActionPreference
$ErrorActionPreference = 'Stop'
try {
do
{
$count = $reader.Read($buffer, 0, $buffer.Length);
if($fileName) {
$writer.Write($buffer, 0, $count);
}

if($Passthru){
$output += $encoding.GetString($buffer,0,$count)
} elseif(!$quiet) {
$total += $count
$totalFormatted = Format-FileSize $total
if($goal -gt 0 -and ++$iterLoop%10 -eq 0) {
Write-Progress "Downloading $url to $fileName" "Saving $totalFormatted of $goalFormatted ($total/$goal)" -id 0 -percentComplete (($total/$goal)*100)
}

if ($total -eq $goal) {
Write-Progress "Completed download of $url." "Completed download of $fileName ($goalFormatted)." -id 0 -Completed
if ($total -eq $goal) {
Write-Progress "Completed download of $url." "Completed download of $fileName ($goalFormatted)." -id 0 -Completed
}
}
}
} while ($count -gt 0)
Write-Host ""
Write-Host "Download of $([System.IO.Path]::GetFileName($fileName)) ($goalFormatted) completed."
} catch {
throw $_.Exception
} finally {
$ErrorActionPreference = $originalEAP
}
} while ($count -gt 0)
Write-Host ""
Write-Host "Download of $([System.IO.Path]::GetFileName($fileName)) ($goalFormatted) completed."
} catch {
throw $_.Exception
} finally {
$ErrorActionPreference = $originalEAP
}

$reader.Close()
if($fileName) {
$writer.Flush()
$writer.Close()
$reader.Close()
if($fileName) {
$writer.Flush()
$writer.Close()
}
if($Passthru){
$output
}
}
} catch {
if ($req -ne $null) {
$req.ServicePoint.MaxIdleTime = 0
$req.Abort();
# ruthlessly remove $req to ensure it isn't reused
Remove-Variable req
Start-Sleep 1
[GC]::Collect()
}
if($Passthru){
$output

throw "The remote file either doesn't exist, is unauthorized, or is forbidden for url '$url'. $($_.Exception.Message)"
} finally {
if ($res -ne $null) {
$res.Close()
}
}
$res.Close();
}

# this could be cleaned up with http://learn-powershell.net/2013/02/08/powershell-and-events-object-events/
25 changes: 15 additions & 10 deletions src/chocolatey.resources/helpers/functions/Get-WebHeaders.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,21 @@ param(
Write-Debug " `'$key`':`'$value`'"
}
}
$response.Close();
}
catch {
$request.ServicePoint.MaxIdleTime = 0
$request.Abort();
# ruthlessly remove $request to ensure it isn't reused
Remove-Variable request
Start-Sleep 1
[GC]::Collect()
throw
} catch {
if ($request -ne $null) {
$request.ServicePoint.MaxIdleTime = 0
$request.Abort();
# ruthlessly remove $request to ensure it isn't reused
Remove-Variable request
Start-Sleep 1
[GC]::Collect()
}

throw "The remote file either doesn't exist, is unauthorized, or is forbidden for url '$url'. $($_.Exception.Message)"
} finally {
if ($response -ne $null) {
$response.Close();
}
}

$headers
Expand Down

0 comments on commit 72934ba

Please sign in to comment.