racket/file: check file-exists?

Check `file-exists?` before passing the file on to `file-size` and/or
`open-input-file`. The latter led to confusing error messages, e.g.:

```
(file->string "DNE")
;; file-size: cannot get size
```

affects: `file->value` `file->list` `file->string` `file->bytes`
 `file->lines` `file->bytes-lines`
This commit is contained in:
Ben Greenman 2020-02-24 20:49:58 -05:00 committed by Sam Tobin-Hochstadt
parent c75881096a
commit d52c845454
2 changed files with 19 additions and 6 deletions

View File

@ -29,6 +29,17 @@
(test #"\"\316\273\"" file->bytes tmp-name)
(test "\u03BB" file->value tmp-name)
(when (file-exists? tmp-name) (delete-file tmp-name))
(define-syntax-rule (err/rt-exists-test (op arg ...))
(err/rt-test (op arg ...) (check-exists 'op)))
(define (check-exists op)
(lambda (exn)
(regexp-match? (format "^~a: .* file-exists\\?" op) (exn-message exn))))
(err/rt-exists-test (file->value tmp-name))
(err/rt-exists-test (file->list tmp-name))
(err/rt-exists-test (file->string tmp-name))
(err/rt-exists-test (file->bytes tmp-name))
(err/rt-exists-test (file->lines tmp-name))
(err/rt-exists-test (file->bytes-lines tmp-name))
(delete-directory tmp-dir)
(define-syntax-rule (err/rt-chk-test (op arg ...))

View File

@ -752,16 +752,18 @@
new (cons base new)))
(loop (cdr paths) (append (reverse new) r))))))))
(define (check-path who f)
(define (check-path-exists who f)
(unless (path-string? f)
(raise-argument-error who "path-string?" f)))
(raise-argument-error who "path-string?" f))
(unless (file-exists? f)
(raise-argument-error who "file-exists?" f)))
(define (check-file-mode who file-mode)
(unless (memq file-mode '(binary text))
(raise-argument-error who "(or/c 'binary 'text)" file-mode)))
(define (file->x who f file-mode read-x x-append)
(check-path who f)
(check-path-exists who f)
(check-file-mode who file-mode)
(let ([sz (file-size f)])
(call-with-input-file* f #:mode file-mode
@ -781,12 +783,12 @@
(file->x 'file->bytes f mode read-bytes bytes-append))
(define (file->value f #:mode [file-mode 'binary])
(check-path 'file->value f)
(check-path-exists 'file->value f)
(check-file-mode 'file->value file-mode)
(call-with-input-file* f #:mode file-mode read))
(define (file->list f [r read] #:mode [file-mode 'binary])
(check-path 'file->list f)
(check-path-exists 'file->list f)
(check-file-mode 'file->list file-mode)
(unless (and (procedure? r) (procedure-arity-includes? r 1))
(raise-argument-error 'file->list "(procedure-arity-includes/c 1)" r))
@ -794,7 +796,7 @@
(lambda (p) (for/list ([v (in-port r p)]) v))))
(define (file->x-lines who f line-mode file-mode read-line)
(check-path who f)
(check-path-exists who f)
(check-mode who line-mode)
(check-file-mode who file-mode)
(call-with-input-file* f #:mode file-mode