Skip to content

Commit 11d1686

Browse files
authored
Fix WorkspaceFilesClient.Stat() silently swallowing non-404 API errors (#4994)
## Changes Fix `WorkspaceFilesClient.Stat()` to propagate non-404 API errors instead of returning zero-value file info with nil error. ## Why When `Stat()` received a non-404 error (e.g. 403 Forbidden, 500 Internal Server Error), it fell through the error handling and returned `(zero-value, nil)`. This caused callers like `workspace export-dir` to silently succeed without exporting anything, and template init to incorrectly report that files already exist. ## Tests Added unit tests covering 403, 500, and 404 error responses from the workspace get-status API.
1 parent c659c3c commit 11d1686

2 files changed

Lines changed: 52 additions & 0 deletions

File tree

libs/filer/workspace_files_client.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,8 @@ func (w *WorkspaceFilesClient) Stat(ctx context.Context, name string) (fs.FileIn
368368
if aerr.StatusCode == http.StatusNotFound {
369369
return nil, fileDoesNotExistError{absPath}
370370
}
371+
372+
return nil, err
371373
}
372374

373375
return stat, nil

libs/filer/workspace_files_client_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import (
66
"testing"
77
"time"
88

9+
"github.com/databricks/cli/libs/testserver"
910
"github.com/databricks/databricks-sdk-go"
11+
"github.com/databricks/databricks-sdk-go/apierr"
1012
"github.com/databricks/databricks-sdk-go/config"
1113
"github.com/databricks/databricks-sdk-go/service/workspace"
1214
"github.com/stretchr/testify/assert"
@@ -131,3 +133,51 @@ func TestWorkspaceFilesClient_wsfsUnmarshal(t *testing.T) {
131133
assert.False(t, info.IsDir())
132134
assert.NotNil(t, info.Sys())
133135
}
136+
137+
func statWithError(t *testing.T, statusCode int, errorCode string) error {
138+
t.Helper()
139+
140+
server := testserver.New(t)
141+
server.Handle("GET", "/api/2.0/workspace/get-status", func(req testserver.Request) any {
142+
return testserver.Response{
143+
StatusCode: statusCode,
144+
Body: map[string]string{
145+
"error_code": errorCode,
146+
"message": "test error",
147+
},
148+
}
149+
})
150+
testserver.AddDefaultHandlers(server)
151+
152+
client, err := databricks.NewWorkspaceClient(&databricks.Config{
153+
Host: server.URL,
154+
Token: "testtoken",
155+
})
156+
require.NoError(t, err)
157+
158+
f, err := NewWorkspaceFilesClient(client, "/test")
159+
require.NoError(t, err)
160+
161+
_, err = f.Stat(t.Context(), "file")
162+
require.Error(t, err)
163+
return err
164+
}
165+
166+
func TestWorkspaceFilesClientStatForbidden(t *testing.T) {
167+
err := statWithError(t, 403, "PERMISSION_DENIED")
168+
var apiErr *apierr.APIError
169+
require.ErrorAs(t, err, &apiErr)
170+
assert.Equal(t, 403, apiErr.StatusCode)
171+
}
172+
173+
func TestWorkspaceFilesClientStatInternalError(t *testing.T) {
174+
err := statWithError(t, 500, "INTERNAL_ERROR")
175+
var apiErr *apierr.APIError
176+
require.ErrorAs(t, err, &apiErr)
177+
assert.Equal(t, 500, apiErr.StatusCode)
178+
}
179+
180+
func TestWorkspaceFilesClientStatNotFound(t *testing.T) {
181+
err := statWithError(t, 404, "RESOURCE_DOES_NOT_EXIST")
182+
assert.ErrorIs(t, err, fs.ErrNotExist)
183+
}

0 commit comments

Comments
 (0)