WEBVTT

00:00:00.700 --> 00:00:07.121
As scripts grow, repeating parsing and normalization code becomes difficult to maintain.

00:00:07.271 --> 00:00:14.986
In this lesson, a small local module owns that reusable work, while main decides which inputs to process

00:00:14.986 --> 00:00:16.701
and what failures mean.

00:00:16.851 --> 00:00:21.288
We will run one valid file and one deliberately broken file.

00:00:21.438 --> 00:00:27.558
The successful result should remain visible, the failure should remain visible, and the batch should

00:00:27.558 --> 00:00:31.230
finish only because we intentionally chose to handle it.

00:00:33.380 --> 00:00:39.695
Our names module exports a function that trims a name and converts its letters to lowercase.

00:00:39.845 --> 00:00:44.517
Export marks this function as part of the module's public interface.

00:00:44.667 --> 00:00:47.888
Helpers without export stay private to the module.

00:00:48.038 --> 00:00:55.367
Keep functions focused so callers can understand their input and result without knowing the internal file

00:00:55.367 --> 00:00:55.825
layout.

00:00:55.975 --> 00:01:03.266
This normalization function does not read files, which also makes it easy to demonstrate with a literal

00:01:03.266 --> 00:01:04.124
test value.

00:01:06.270 --> 00:01:14.859
Load_name combines three responsibilities in an explicit sequence: read text, parse JSON, and require the

00:01:14.859 --> 00:01:17.150
name field before normalization.

00:01:17.300 --> 00:01:20.415
Require expresses that the field must exist.

00:01:20.565 --> 00:01:26.730
A missing required field should not accidentally flow onward as a successful empty name.

00:01:26.880 --> 00:01:34.514
This lesson keeps the schema small; applications may also need to validate the field's type and business

00:01:34.514 --> 00:01:35.861
rules before normalization.

00:01:36.011 --> 00:01:40.171
Failures propagate to the caller until somebody handles them.

00:01:42.320 --> 00:01:47.696
The import path is resolved relative to the source file containing the import.

00:01:47.846 --> 00:01:54.455
This differs from the data filename passed into our loader, which is resolved from the process working

00:01:54.455 --> 00:01:54.843
directory.

00:01:54.993 --> 00:01:57.895
Run from examples as the README instructs.

00:01:58.045 --> 00:02:05.682
The module is loaded and cached, so ordinary repeated imports do not repeatedly execute its top level.

00:02:05.832 --> 00:02:12.317
Choose explicit exports and small modules before building a complicated directory hierarchy.

00:02:14.470 --> 00:02:17.585
The broken fixture is not valid JSON.

00:02:17.735 --> 00:02:24.199
Catch receives the Error that propagates out of load_name, and our demonstration prints its category.

00:02:24.349 --> 00:02:27.143
The observed category here is ValueError.

00:02:27.293 --> 00:02:32.563
Error values also carry diagnostic information such as code and message.

00:02:32.713 --> 00:02:37.001
Handle errors where you have enough context to decide what to do.

00:02:37.151 --> 00:02:44.489
A catch block that merely hides a failure can make an unsuccessful operation look deceptively complete.

00:02:46.640 --> 00:02:50.715
An unhandled error in a stream normally ends that pipeline.

00:02:50.865 --> 00:02:58.161
Attempt changes the contract for one operation: it returns a Result representing success or failure.

00:02:58.311 --> 00:03:04.973
That lets our batch retain an outcome for each filename instead of losing the whole demonstration at the

00:03:04.973 --> 00:03:05.713
broken file.

00:03:05.863 --> 00:03:08.914
Notice the explicit stream conversion on the List.

00:03:09.064 --> 00:03:16.445
Also notice that attempt belongs inside the callback, so each input gets its own individual outcome.

00:03:18.600 --> 00:03:23.229
Check result dot ok before accessing the branch specific value.

00:03:23.379 --> 00:03:28.222
A successful Result provides value; a failed Result provides error.

00:03:28.372 --> 00:03:33.471
We print both branches, so the report does not silently discard bad input.

00:03:33.621 --> 00:03:39.551
Production reports should usually include the input identity alongside each outcome.

00:03:39.701 --> 00:03:45.952
Runtime cleanup still applies when operations fail, but it cannot choose your business policy.

00:03:46.102 --> 00:03:50.582
You must decide whether partial success is acceptable for the job.

00:03:52.730 --> 00:03:56.015
Run the separate fail script to see the other policy.

00:03:56.165 --> 00:04:03.440
It calls the same loader on the broken fixture without catch or attempt, so the command exits nonzero.

00:04:03.590 --> 00:04:08.369
That is useful when a job must not continue after invalid input.

00:04:08.519 --> 00:04:15.708
The reusable module stays unchanged; orchestration determines whether errors are fatal or collected.

00:04:15.858 --> 00:04:22.450
Avoid catching everything at the deepest function merely to prevent an error from reaching its caller.

00:04:24.600 --> 00:04:29.208
For practice, add a valid JSON fixture that lacks the name field.

00:04:29.358 --> 00:04:36.290
Predict whether parsing or require will reject it, then include it in the batch and inspect its error

00:04:36.290 --> 00:04:36.675
category.

00:04:36.825 --> 00:04:41.967
Next, add the filename to each printed outcome so the report is actionable.

00:04:42.117 --> 00:04:45.765
Keep fail as a separate example of a fatal policy.

00:04:45.915 --> 00:04:53.872
You now have reusable modules, a clear import rule, and two deliberate ways to handle unsuccessful work.

