Skip to content

Discussion, demonstrating error handling #316

Open
@bencoman

Description

@bencoman

Tim & Sam, Seeking your opinions. Pharo has a powerful and flexible exception handling system that I don't feel we are demonstrating. As I've been working through the Bowling exercise, I've developed some concerns with this test pattern...

test15_RollsCannotScoreNegativePoints
	| result |
	self
		should: [ result := bowlingCalculator scoreRolling: -1 after: #() ]
		raise: BowlingError
		whoseDescriptionIncludes: 'Negative roll is invalid'
		description: 'Should get an error with the correct description'

because:

  1. It doesn't teach students how errors to handle errors in application code.
    I feel the following teaches students more...
test15_RollsCannotScoreNegativePoints
	| testError |
	[ bowlingCalculator scoreRolling: -1 after: #() ] 
		on: Error do: [ :error | testError := error ].
	self assert: testError notNil.	
	self assert: testError description equals: 'Negative roll is invalid'.  
  1. Its using a facility not in the base image, so students can be confused when they try to copy the pattern in their own projects. [EDIT: Whoops, my presumption was wrong. It is in the base image]
  2. The Error-instance is not available for inspection.
  3. With my Bowling solution I want to demonstrate the use of custom errors by seeding the following with the downloaded exercise...
Error subclass: #BowlingError
	instanceVariableNames: 'artifact description'
	classVariableNames: ''
	package: 'Exercism-Bowling'

BowlingError>>artifact: anObject
	artifact := anObject 

BowlingError>>artifact
	^ artifact

BowlingError>>description: errorString
	description := errorString

BowlingError>>description
	^ 'Bowling error: ' , description

Frame>>raiseBowlingError: errorString artifact: anObject
	<exercismHint>
	"Raises a custom error with state holding the troublesome entity"
	(BowlingError new artifact: anObject; description: errorString) signal

FrameTest>>test16_customError
	| error |
	[ Frame new raiseBowlingError: 'My custom error' artifact: 42] 
		on: BowlingError do: [ :err | error := err ].
	self assert: error notNil.	
	self assert: (error description includesSubstring: 'My custom error').
	self assert: error artifact equals: 42.

FrameTest>>test17_negativeRollError
	| error |
	[ Frame new roll: -1 ] 
		on: BowlingError do: [ :err | error := err ].
	self assert: error notNil.	
	self assert: (error description includesSubstring: 'Negative roll is invalid').  
	self assert: error artifact equals: -1

and leave students to write...

Frame>>roll: anInteger 
	anInteger < 0 ifTrue: [ self raiseBowlingError: 'Negative roll is invalid' artifact: anInteger ].
	self isFull ifTrue: [ ^ self nextFrame roll: anInteger ].
	frameRolls add: anInteger

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions