diff --git a/src/Decoder.ts b/src/Decoder.ts index 6ee7fbf..2a97f3e 100644 --- a/src/Decoder.ts +++ b/src/Decoder.ts @@ -215,9 +215,9 @@ export const array = (decoder: Decoder): Decoder => } return value.reduce((memo: Result, element, idx) => { - const result = decoder.decodeAny(element); return memo.andThen(results => { - return result + return decoder + .decodeAny(element) .mapError(s => `I found an error in the array at [${idx}]: ${s}`) .map(v => results.concat([v])); }); @@ -260,6 +260,11 @@ export const at = ( decoder: Decoder ): Decoder => new Decoder(value => { + if (value == null) { + return err( + `I found an error. Could not apply 'at' path to an undefined or null value.` + ); + } let val = value; let idx = 0; while (idx < path.length) { diff --git a/tests/Decoder.test.ts b/tests/Decoder.test.ts index 3c3ac8d..f0b7bac 100644 --- a/tests/Decoder.test.ts +++ b/tests/Decoder.test.ts @@ -1,19 +1,5 @@ import * as test from 'tape'; -import { - array, - at, - boolean, - date, - dict, - field, - keyValuePairs, - maybe, - nullable, - number, - oneOf, - string, - succeed, -} from '../src/index'; +import { array, at, boolean, date, dict, field, keyValuePairs, maybe, nullable, number, oneOf, string, succeed } from '../src/index'; test('string decoder', t => { string.decodeJson('"foo"').cata({ @@ -148,6 +134,13 @@ test('at decoder', t => { Ok: v => t.pass(`at is compatible with nullable`), }); + at(['foo', 0, 'bar'], number) + .decodeAny(undefined) + .cata({ + Err: () => t.pass(`at-ing an undefined to should be an error, but not crash`), + Ok: () => t.fail(`at-ing an undefined should not pass`), + }); + t.end(); });