Skip to content

Commit

Permalink
pass file system errors to callers (#348)
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Aug 26, 2020
1 parent 9882ae3 commit b2ae710
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 83 deletions.
9 changes: 4 additions & 5 deletions cmd/esbuild/service.go
Expand Up @@ -13,7 +13,6 @@ import (
"os"
"runtime/debug"
"sync"
"syscall"

"github.com/evanw/esbuild/internal/fs"
"github.com/evanw/esbuild/pkg/api"
Expand Down Expand Up @@ -239,11 +238,11 @@ func (service *serviceType) handleTransformRequest(id uint32, request map[string
transformInput := input
if inputFS {
realFS := fs.RealFS()
bytes, ok := realFS.ReadFile(input)
if !ok {
return encodeErrorPacket(id, syscall.ENOENT)
bytes, err := realFS.ReadFile(input)
if err == nil {
err = os.Remove(input)
}
if err := os.Remove(input); err != nil {
if err != nil {
return encodeErrorPacket(id, err)
}
transformInput = string(bytes)
Expand Down
30 changes: 20 additions & 10 deletions internal/bundler/bundler.go
Expand Up @@ -12,6 +12,7 @@ import (
"sort"
"strings"
"sync"
"syscall"
"unicode"
"unicode/utf8"

Expand Down Expand Up @@ -118,11 +119,16 @@ func parseFile(args parseArgs) {
loader = stdin.Loader
} else if args.keyPath.IsAbsolute {
// Read normal modules from disk
var ok bool
source.Contents, ok = args.res.Read(args.keyPath.Text)
if !ok {
args.log.AddRangeError(args.importSource, args.pathRange,
fmt.Sprintf("Could not read from file: %s", args.keyPath.Text))
var err error
source.Contents, err = args.fs.ReadFile(args.keyPath.Text)
if err != nil {
if err == syscall.ENOENT {
args.log.AddRangeError(args.importSource, args.pathRange,
fmt.Sprintf("Could not read from file: %s", args.keyPath.Text))
} else {
args.log.AddRangeError(args.importSource, args.pathRange,
fmt.Sprintf("Cannot read file %q: %s", args.res.PrettyPath(args.keyPath.Text), err.Error()))
}
args.results <- parseResult{}
return
}
Expand Down Expand Up @@ -305,7 +311,7 @@ func parseFile(args parseArgs) {

// Attempt to parse the source map if present
if loader.CanHaveSourceMap() && args.options.SourceMap != config.SourceMapNone && result.file.ast.SourceMapComment.Text != "" {
if path, contents := extractSourceMapFromComment(args.log, args.fs, &source, result.file.ast.SourceMapComment); contents != nil {
if path, contents := extractSourceMapFromComment(args.log, args.fs, args.res, &source, result.file.ast.SourceMapComment); contents != nil {
prettyPath := path.Text
if path.IsAbsolute {
prettyPath = args.res.PrettyPath(prettyPath)
Expand All @@ -321,7 +327,7 @@ func parseFile(args parseArgs) {
args.results <- result
}

func extractSourceMapFromComment(log logging.Log, fs fs.FS, source *logging.Source, comment ast.Span) (ast.Path, *string) {
func extractSourceMapFromComment(log logging.Log, fs fs.FS, res resolver.Resolver, source *logging.Source, comment ast.Span) (ast.Path, *string) {
// Data URL
if strings.HasPrefix(comment.Text, "data:") {
if strings.HasPrefix(comment.Text, "data:application/json;") {
Expand All @@ -348,9 +354,13 @@ func extractSourceMapFromComment(log logging.Log, fs fs.FS, source *logging.Sour
// Absolute path
if source.KeyPath.IsAbsolute {
absPath := fs.Join(fs.Dir(source.KeyPath.Text), comment.Text)
contents, ok := fs.ReadFile(absPath)
if !ok {
log.AddRangeWarning(source, comment.Range, fmt.Sprintf("Could not find source map file: %s", absPath))
contents, err := fs.ReadFile(absPath)
if err != nil {
if err == syscall.ENOENT {
log.AddRangeWarning(source, comment.Range, fmt.Sprintf("Could not find source map file: %s", absPath))
return ast.Path{}, nil
}
log.AddRangeError(source, comment.Range, fmt.Sprintf("Cannot read file %q: %s", res.PrettyPath(absPath), err.Error()))
return ast.Path{}, nil
}
return ast.Path{IsAbsolute: true, Text: absPath}, &contents
Expand Down
19 changes: 14 additions & 5 deletions internal/fs/fs.go
Expand Up @@ -7,6 +7,7 @@ import (
"path/filepath"
"strings"
"sync"
"syscall"
)

type EntryKind uint8
Expand Down Expand Up @@ -90,7 +91,7 @@ type FS interface {
// The returned map is immutable and is cached across invocations. Do not
// mutate it.
ReadDirectory(path string) map[string]*Entry
ReadFile(path string) (string, bool)
ReadFile(path string) (string, error)

// This is part of the interface because the mock interface used for tests
// should not depend on file system behavior (i.e. different slashes for
Expand Down Expand Up @@ -146,9 +147,12 @@ func (fs *mockFS) ReadDirectory(path string) map[string]*Entry {
return fs.dirs[path]
}

func (fs *mockFS) ReadFile(path string) (string, bool) {
func (fs *mockFS) ReadFile(path string) (string, error) {
contents, ok := fs.files[path]
return contents, ok
if !ok {
return "", syscall.ENOENT
}
return contents, nil
}

func (*mockFS) Abs(p string) (string, bool) {
Expand Down Expand Up @@ -315,11 +319,16 @@ func (fs *realFS) ReadDirectory(dir string) map[string]*Entry {
return entries
}

func (fs *realFS) ReadFile(path string) (string, bool) {
func (fs *realFS) ReadFile(path string) (string, error) {
BeforeFileOpen()
defer AfterFileClose()
buffer, err := ioutil.ReadFile(path)
return string(buffer), err == nil
if err != nil {
if pathErr, ok := err.(*os.PathError); ok {
return "", pathErr.Unwrap()
}
}
return string(buffer), err
}

func (*realFS) Abs(p string) (string, bool) {
Expand Down
12 changes: 6 additions & 6 deletions internal/fs/fs_test.go
Expand Up @@ -14,23 +14,23 @@ func TestBasic(t *testing.T) {
})

// Test a missing file
_, ok := fs.ReadFile("/missing.txt")
if ok {
_, err := fs.ReadFile("/missing.txt")
if err == nil {
t.Fatal("Unexpectedly found /missing.txt")
}

// Test an existing file
readme, ok := fs.ReadFile("/README.md")
if !ok {
readme, err := fs.ReadFile("/README.md")
if err != nil {
t.Fatal("Expected to find /README.md")
}
if readme != "// README.md" {
t.Fatalf("Incorrect contents for /README.md: %q", readme)
}

// Test an existing nested file
index, ok := fs.ReadFile("/src/index.js")
if !ok {
index, err := fs.ReadFile("/src/index.js")
if err != nil {
t.Fatal("Expected to find /src/index.js")
}
if index != "// src/index.js" {
Expand Down

0 comments on commit b2ae710

Please sign in to comment.