From d52c84545425d4436d3bfb47743c2c3a2dd4aa7b Mon Sep 17 00:00:00 2001 From: Ben Greenman Date: Mon, 24 Feb 2020 20:49:58 -0500 Subject: [PATCH] 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` --- pkgs/racket-test-core/tests/racket/filelib.rktl | 11 +++++++++++ racket/collects/racket/file.rkt | 14 ++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/filelib.rktl b/pkgs/racket-test-core/tests/racket/filelib.rktl index aa289a4a63..9bfbf97c0f 100644 --- a/pkgs/racket-test-core/tests/racket/filelib.rktl +++ b/pkgs/racket-test-core/tests/racket/filelib.rktl @@ -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 ...)) diff --git a/racket/collects/racket/file.rkt b/racket/collects/racket/file.rkt index 64a28f6458..3ae352ba09 100644 --- a/racket/collects/racket/file.rkt +++ b/racket/collects/racket/file.rkt @@ -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