Challenge 3: A Structured Exception — Possible Solution ==================================================================== use strict; use warnings; use feature 'say', 'try'; no warnings 'experimental::try'; sub validate_number { my ($n) = @_; die { code => 400, message => "Bad input" } if $n < 0; return $n; } try { validate_number(-5); } catch ($e) { say "Code: $e->{code}"; say "Message: $e->{message}"; } Output: Code: 400 Message: Bad input WHY THIS WORKS AS AN ANSWER ------------------------------ die { code => 400, message => "Bad input" } if $n < 0; reuses the chapter's own die-with-a-reference example directly — an anonymous hashref (Course 1, Chapter 9) is passed to die instead of a plain string, combined with Course 1, Chapter 5's postfix conditional. try { ... } catch ($e) { ... } reuses this chapter's own modern error-handling syntax, exactly as in Challenge 1 — but here, per the chapter's own explanation, $e becomes the ACTUAL HASHREF that was died with, not a stringified message, since "die accepts a reference just as readily as a string" and "$@ (or $e...) becomes that exact reference." $e->{code} and $e->{message} reuse the chapter's own arrow- dereference access pattern (Course 1, Chapter 9) to pull the structured pieces back out of the caught exception separately — this is precisely the advantage the chapter names structured exceptions as having over plain string messages: the catching code can inspect individual pieces of data (a numeric code, a human-readable message) rather than needing to parse or pattern-match a single flat string.