Skip to content

Commit 2ef3f89

Browse files
committed
Integrate copyediting for Chapter 8
1 parent 5a7f881 commit 2ef3f89

File tree

1 file changed

+19
-15
lines changed

1 file changed

+19
-15
lines changed

08_error.md

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,21 @@ quote}}
1414

1515
Flaws in computer programs are usually called _((bug))s_. It makes programmers feel good to imagine them as little things that just happen to crawl into our work. In reality, of course, we put them there ourselves.
1616

17-
If a program is crystallized thought, you can roughly categorize bugs into those caused by the thoughts being confused and those caused by mistakes introduced while converting a thought to code. The former type is generally harder to diagnose and fix than the latter.
17+
If a program is crystallized thought, we can roughly categorize bugs into those caused by the thoughts being confused and those caused by mistakes introduced while converting a thought to code. The former type is generally harder to diagnose and fix than the latter.
1818

1919
## Language
2020

2121
{{index parsing, analysis}}
2222

23-
Many mistakes could be pointed out to us automatically by the computer, if it knew enough about what we're trying to do. But here JavaScript's looseness is a hindrance. Its concept of bindings and properties is vague enough that it will rarely catch ((typo))s before actually running the program. And even then, it allows you to do some clearly nonsensical things without complaint, such as computing `true * "monkey"`.
23+
Many mistakes could be pointed out to us automatically by the computer, if it knew enough about what we're trying to do. But here JavaScript's looseness is a hindrance. Its concept of bindings and properties is vague enough that it will rarely catch ((typo))s before actually running the program. Even then, it allows you to do some clearly nonsensical things without complaint, such as computing `true * "monkey"`.
2424

2525
{{index [syntax, error], [property, access]}}
2626

2727
There are some things that JavaScript does complain about. Writing a program that does not follow the language's ((grammar)) will immediately make the computer complain. Other things, such as calling something that's not a function or looking up a property on an ((undefined)) value, will cause an error to be reported when the program tries to perform the action.
2828

2929
{{index NaN, error}}
3030

31-
But often, your nonsense computation will merely produce `NaN` (not a number) or an undefined value, while the program happily continues, convinced that it's doing something meaningful. The mistake will manifest itself only later, after the bogus value has traveled through several functions. It might not trigger an error at all but silently cause the program's output to be wrong. Finding the source of such problems can be difficult.
31+
Often, however, your nonsense computation will merely produce `NaN` (not a number) or an undefined value, while the program happily continues, convinced that it's doing something meaningful. The mistake will manifest itself only later, after the bogus value has traveled through several functions. It might not trigger an error at all but silently cause the program's output to be wrong. Finding the source of such problems can be difficult.
3232

3333
The process of finding mistakes—bugs—in programs is called _((debugging))_.
3434

@@ -38,7 +38,7 @@ The process of finding mistakes—bugs—in programs is called _((debugging))_.
3838

3939
{{indexsee "use strict", "strict mode"}}
4040

41-
JavaScript can be made a _little_ stricter by enabling _strict mode_. This is done by putting the string `"use strict"` at the top of a file or a function body. Here's an example:
41+
JavaScript can be made a _little_ stricter by enabling _strict mode_. This can done by putting the string `"use strict"` at the top of a file or a function body. Here's an example:
4242

4343
```{test: "error \"ReferenceError: counter is not defined\""}
4444
function canYouSpotTheProblem() {
@@ -52,6 +52,10 @@ canYouSpotTheProblem();
5252
// → ReferenceError: counter is not defined
5353
```
5454

55+
{{index ECMAScript, compatibility}}
56+
57+
Code inside classes and modules (which we will discuss in [Chapter ?](modules)) is automatically strict. The old non-strict behavior still exists only because some old code might depend on it, and the language designers work hard to avoid breaking any existing programs.
58+
5559
{{index "let keyword", [binding, global]}}
5660

5761
Normally, when you forget to put `let` in front of your binding, as with `counter` in the example, JavaScript quietly creates a global binding and uses that. In strict mode, an ((error)) is reported instead. This is very helpful. It should be noted, though, that this doesn't work when the binding in question already exists somewhere in scope. In that case, the loop will still quietly overwrite the value of the binding.
@@ -71,7 +75,7 @@ console.log(name);
7175

7276
{{index error}}
7377

74-
So the bogus call to `Person` succeeded but returned an undefined value and created the global binding `name`. In strict mode, the result is different.
78+
The bogus call to `Person` succeeded but returned an undefined value and created the global binding `name`. In strict mode, the result is different.
7579

7680
```{test: "error \"TypeError: Cannot set properties of undefined (setting 'name')\""}
7781
"use strict";
@@ -196,7 +200,7 @@ Even if you see the problem already, pretend for a moment that you don't. We kno
196200

197201
{{index "trial and error"}}
198202

199-
This is where you must resist the urge to start making random changes to the code to see whether that makes it better. Instead, _think_. Analyze what is happening and come up with a ((theory)) of why it might be happening. Then, make additional observations to test this theory—or, if you don't yet have a theory, make additional observations to help you come up with one.
203+
This is where you must resist the urge to start making random changes to the code to see whether that makes it better. Instead, _think_. Analyze what is happening and come up with a ((theory)) of why it might be happening. Then make additional observations to test this theory—or, if you don't yet have a theory, make additional observations to help you come up with one.
200204

201205
{{index "console.log", output, debugging, logging}}
202206

@@ -219,7 +223,7 @@ _Right_. Dividing 13 by 10 does not produce a whole number. Instead of `n /= bas
219223

220224
An alternative to using `console.log` to peek into the program's behavior is to use the _debugger_ capabilities of your browser. Browsers come with the ability to set a _((breakpoint))_ on a specific line of your code. When the execution of the program reaches a line with a breakpoint, it is paused, and you can inspect the values of bindings at that point. I won't go into details, as debuggers differ from browser to browser, but look in your browser's ((developer tools)) or search the Web for instructions.
221225

222-
Another way to set a breakpoint is to include a `debugger` statement (consisting of simply that keyword) in your program. If the ((developer tools)) of your browser are active, the program will pause whenever it reaches such a statement.
226+
Another way to set a breakpoint is to include a `debugger` statement (consisting simply of that keyword) in your program. If the ((developer tools)) of your browser are active, the program will pause whenever it reaches such a statement.
223227

224228
## Error propagation
225229

@@ -229,15 +233,15 @@ Not all problems can be prevented by the programmer, unfortunately. If your prog
229233

230234
{{index "error recovery"}}
231235

232-
If you're programming only for yourself, you can afford to just ignore such problems until they occur. But if you build something that is going to be used by anybody else, you usually want the program to do better than just crash. Sometimes the right thing to do is take the bad input in stride and continue running. In other cases, it is better to report to the user what went wrong and then give up. But in either situation, the program has to actively do something in response to the problem.
236+
If you're programming only for yourself, you can afford to just ignore such problems until they occur. But if you build something that is going to be used by anybody else, you usually want the program to do better than just crash. Sometimes the right thing to do is take the bad input in stride and continue running. In other cases, it is better to report to the user what went wrong and then give up. In either situation the program has to actively do something in response to the problem.
233237

234238
{{index "promptNumber function", validation}}
235239

236240
Say you have a function `promptNumber` that asks the user for a number and returns it. What should it return if the user inputs "orange"?
237241

238242
{{index null, undefined, "return value", "special return value"}}
239243

240-
One option is to make it return a special value. Common choices for such values are `null`, `undefined`, or -1.
244+
One option is to make it return a special value. Common choices for such values are `null`, `undefined`, or `-1`.
241245

242246
```{test: no}
243247
function promptNumber(question) {
@@ -267,7 +271,7 @@ function lastElement(array) {
267271

268272
{{index "special return value", readability}}
269273

270-
The second issue with returning special values is that it can lead to awkward code. If a piece of code calls `promptNumber` 10 times, it has to check 10 times whether `null` was returned. And if its response to finding `null` is to simply return `null` itself, callers of the function will in turn have to check for it, and so on.
274+
The second issue with returning special values is that it can lead to awkward code. If a piece of code calls `promptNumber` 10 times, it has to check 10 times whether `null` was returned. If its response to finding `null` is to simply return `null` itself, callers of the function will in turn have to check for it, and so on.
271275

272276
## Exceptions
273277

@@ -277,7 +281,7 @@ When a function cannot proceed normally, what we would often _like_ to do is jus
277281

278282
{{index ["control flow", exceptions], "raising (exception)", "throw keyword", "call stack"}}
279283

280-
Exceptions are a mechanism that makes it possible for code that runs into a problem to _raise_ (or _throw_) an exception. An exception can be any value. Raising one somewhat resembles a super-charged return from a function: it jumps out of not just the current function but also its callers, all the way down to the first call that started the current execution. This is called _((unwinding the stack))_. You may remember the stack of function calls that was mentioned in [Chapter ?](functions#stack). An exception zooms down this stack, throwing away all the call contexts it encounters.
284+
Exceptions are a mechanism that makes it possible for code that runs into a problem to _raise_ (or _throw_) an exception. An exception can be any value. Raising one somewhat resembles a super-charged return from a function: it jumps out of not just the current function but also its callers, all the way down to the first call that started the current execution. This is called _((unwinding the stack))_. You may remember the stack of function calls mentioned in [Chapter ?](functions#stack). An exception zooms down this stack, throwing away all the call contexts it encounters.
281285

282286
{{index "error handling", [syntax, statement], "catch keyword"}}
283287

@@ -333,7 +337,7 @@ This means when code has several side effects, even if its "regular" control flo
333337

334338
{{index "banking example"}}
335339

336-
Here is some really bad banking code.
340+
Here is some really bad banking code:
337341

338342
```{includeCode: true}
339343
const accounts = {
@@ -367,7 +371,7 @@ One way to address this is to use fewer side effects. Again, a programming style
367371

368372
{{index block, "try keyword", "finally keyword"}}
369373

370-
But that isn't always practical. So there is another feature that `try` statements have. They may be followed by a `finally` block either instead of or in addition to a `catch` block. A `finally` block says "no matter _what_ happens, run this code after trying to run the code in the `try` block."
374+
Since that isn't always practical, `try` statements have another feature: they may be followed by a `finally` block either instead of or in addition to a `catch` block. A `finally` block says "no matter _what_ happens, run this code after trying to run the code in the `try` block."
371375

372376
```{includeCode: true}
373377
function transfer(from, amount) {
@@ -438,13 +442,13 @@ for (;;) {
438442

439443
{{index "infinite loop", "for loop", "catch keyword", debugging}}
440444

441-
The `for (;;)` construct is a way to intentionally create a loop that doesn't terminate on its own. We break out of the loop only when a valid direction is given. _But_ we misspelled `promptDirection`, which will result in an "undefined variable" error. Because the `catch` block completely ignores its exception value (`e`), assuming it knows what the problem is, it wrongly treats the binding error as indicating bad input. Not only does this cause an infinite loop, it "buries" the useful error message about the misspelled binding.
445+
The `for (;;)` construct is a way to intentionally create a loop that doesn't terminate on its own. We break out of the loop only when a valid direction is given. Unfortunately, we misspelled `promptDirection`, which will result in an "undefined variable" error. Because the `catch` block completely ignores its exception value (`e`), assuming it knows what the problem is, it wrongly treats the binding error as indicating bad input. Not only does this cause an infinite loop, it "buries" the useful error message about the misspelled binding.
442446

443447
As a general rule, don't blanket-catch exceptions unless it is for the purpose of "routing" them somewhere—for example, over the network to tell another system that our program crashed. And even then, think carefully about how you might be hiding information.
444448

445449
{{index "exception handling"}}
446450

447-
So we want to catch a _specific_ kind of exception. We can do this by checking in the `catch` block whether the exception we got is the one we are interested in and rethrowing it otherwise. But how do we recognize an exception?
451+
We want to catch a _specific_ kind of exception. We can do this by checking in the `catch` block whether the exception we got is the one we are interested in, and if not, rethrow it. But how do we recognize an exception?
448452

449453
We could compare its `message` property against the ((error)) message we happen to expect. But that's a shaky way to write code—we'd be using information that's intended for human consumption (the message) to make a programmatic decision. As soon as someone changes (or translates) the message, the code will stop working.
450454

0 commit comments

Comments
 (0)