Skip to content

Commit

Permalink
[New Exercise]: Error Handling (#330)
Browse files Browse the repository at this point in the history
  • Loading branch information
glaxxie authored Jan 11, 2024
1 parent 4510951 commit 48a35f5
Show file tree
Hide file tree
Showing 7 changed files with 268 additions and 0 deletions.
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,14 @@
"prerequisites": [],
"difficulty": 2
},
{
"slug": "error-handling",
"name": "Error Handling",
"uuid": "1813c9f6-a653-43b1-a835-5b9edcbd1c68",
"practices": [],
"prerequisites": [],
"difficulty": 3
},
{
"slug": "wordy",
"name": "Wordy",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# PowerShell track

The functions in the exercise are short and not supposed to be complicated.

However reading about [Exceptions](https://learn.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-exceptions), and understanding the test suite is strongly recommended before starting.
8 changes: 8 additions & 0 deletions exercises/practice/error-handling/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Instructions

Implement various kinds of error handling and resource management.

An important point of programming is how to handle errors and close resources even if errors occur.

This exercise requires you to handle various errors.
Because error handling is rather programming language specific you'll have to refer to the tests for your track to see what's exactly required.
96 changes: 96 additions & 0 deletions exercises/practice/error-handling/.meta/ErrorHandling.example.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
Function ValidateAge() {
<#
.SYNOPSIS
Simple function to check if the input age is over 18.
.DESCRIPTION
This is a function to validate an age.
It will throw a termination error when :
a. The input value for the Age param won't satisfy the ValidateScript
b. The input value doesn't match the expected type [int]
Do not delete or modify this.
.PARAMETER Age
An integer represent the age, it should be 18 or up.
#>
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[ValidateScript({$_ -ge 18},
ErrorMessage = "'{0}' is not a valid age. Valid value is 18 and up")]
[int] $Age
)
return "I'm $Age years old!"
}

#Start all your code below this
Function NonTerminationError {
<#
.DESCRIPTION
A simple function that return an error message but doesnt terminate the function.
#>
Write-Error "Error: This is a non termination error"
}

Function ValueErrorHandling {
<#
.DESCRIPTION
A function that take in an input for the predefined ValidateAge function, it may catch error and return normal string with a warning message.
#>
param (
$Age
)
try {
ValidateAge -Age $Age
}
catch {
Write-Output "Error: Age need to be 18 and up"
}
}

Function TypedErrorHandling {
<#
.DESCRIPTION
A function that take in a string represent a path to open a file.
This function should handle 2 different termination errors:
- File not found
- File path is too long (256)
.PARAMETER Path
String represent a filepath.
#>
param (
[string] $Path
)
try {
if ($Path.Length -gt 256) {
Write-Error -Exception ([System.IO.PathTooLongException]::new()) -ErrorAction Stop
}
Get-Content -Path $Path -ErrorAction Stop
}
catch [System.IO.PathTooLongException]{
Write-Output $_.ToString()
}
catch [System.Management.Automation.ItemNotFoundException]{
Write-Output "Error: File not found"
}
}

Function ReThrowErrorHandling {
<#
.DESCRIPTION
A simple function to demonstrate the ability to rethrow a different error.
Instead of throwing a filepath not exist, throw a custom error when the Path parameter wasn't provided.
#>
param (
[string] $Path
)
try {
Get-Content -Path $Path
}
catch {
if ($Path.Length -eq 0) {
throw "Error: Path wasn't provided."
}
}
}
17 changes: 17 additions & 0 deletions exercises/practice/error-handling/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"authors": [
"glaxxie"
],
"files": {
"solution": [
"ErrorHandling.ps1"
],
"test": [
"ErrorHandling.tests.ps1"
],
"example": [
".meta/ErrorHandling.example.ps1"
]
},
"blurb": "Implement various kinds of error handling and resource management."
}
73 changes: 73 additions & 0 deletions exercises/practice/error-handling/ErrorHandling.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
Function ValidateAge() {
<#
.SYNOPSIS
Simple function to check if the input age is over 18.
.DESCRIPTION
This is a function to validate an age.
It will throw a termination error when :
a. The input value for the Age param won't satisfy the ValidateScript
b. The input value doesn't match the expected type [int]
Do not delete or modify this.
.PARAMETER Age
An integer represent the age, it should be 18 or up.
#>
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
[ValidateScript({$_ -ge 18},
ErrorMessage = "'{0}' is not a valid age. Valid value is 18 and up")]
[int] $Age
)
return "I'm $Age years old!"
}

#Start all your code below this
Function NonTerminationError {
<#
.DESCRIPTION
A simple function that return an error message but doesnt terminate the function.
#>
Throw "Please implement this function"
}

Function ValueErrorHandling {
<#
.DESCRIPTION
A function that take in an input for the predefined ValidateAge function, it may catch error and return normal string with a warning message.
#>
param (
$Age
)
Throw "Please implement this function"
}

Function TypedErrorHandling {
<#
.DESCRIPTION
A function that take in a string represent a path to open a file.
This function should handle 2 different termination errors:
- File not found
- File path is too long (256)
.PARAMETER Path
String represent a filepath.
#>
param (
[string] $Path
)
Throw "Please implement this function"
}

Function ReThrowErrorHandling {
<#
.DESCRIPTION
A simple function to demonstrate the ability to rethrow a different error.
Instead of throwing a filepath not exist, throw a custom error when the Path parameter wasn't provided.
#>
param (
[string] $Path
)
Throw "Please implement this function"
}
61 changes: 61 additions & 0 deletions exercises/practice/error-handling/ErrorHandling.tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
BeforeAll {
. "./ErrorHandling.ps1"
}

Describe "ErrorHandling test cases" {
BeforeEach {
#The Error variable is used to store all the errors that occured.
#Before each test, this got run so the count will be reflected correctly for each case.
$Error.Clear()
}

It "non terminal error" {
#This got enable so it won't show the error msg in pester.
$ErrorActionPreference = "SilentlyContinue"
NonTerminationError

#However there is still an $Error variable with value in it to be run against for testing
$Error.Count | Should -BeGreaterThan 0
$Error[0].Exception.Message | Should -Contain "Error: This is a non termination error"
}

It "ValueErrorHandling : valid input" {
$got = ValueErrorHandling -Age 25
$want = "I'm 25 years old!"

$got | Should -BeExactly $want
}

It "ValueErrorHandling : invalid inputs" {
$got1 = ValueErrorHandling -Age "ten"
$want1 = "Error: Age need to be 18 and up"

$got1 | Should -BeExactly $want1
$Error.Count | Should -Be 1


$got2 = ValueErrorHandling -Age 14
$want2 = "Error: Age need to be 18 and up"

$got2 | Should -BeExactly $want2
$Error.Count | Should -Be 2
}

It "multiple terminal error catch: file not found - with custom error message" {
$got = TypedErrorHandling -Path "nonexistant"
$want = "Error: File not found"

$got | Should -BeExactly $want
}

It "multiple terminal error catch: file path is too long - defaul error message" {
$got = TypedErrorHandling -Path ("nonexistant" * 50)
$want = "The specified file name or path is too long, or a component of the specified path is too long."

$got | Should -BeExactly $want
}

It "rethrow error" {
{ ReThrowErrorHandling } | Should -Throw "*Error: Path wasn't provided.*"
}
}

0 comments on commit 48a35f5

Please sign in to comment.