Skip to content

Commit 25499f4

Browse files
committed
Improve error handling for native tools
1 parent 5c0de08 commit 25499f4

2 files changed

Lines changed: 30 additions & 12 deletions

File tree

src/eca/features/tools/filesystem.clj

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,27 @@
1111
:content text
1212
:error (boolean error)}]})
1313

14-
(defn ^:private not-allowed-path [path db]
15-
(when (not-any? #(fs/starts-with? path (shared/uri->filename (:uri %)))
16-
(:workspace-folders db))
17-
(single-text-content "Access denied - path outside workspace root, call list_allowed_dirs first")))
14+
(defn ^:private allowed-path? [db path]
15+
(some #(fs/starts-with? path (shared/uri->filename (:uri %)))
16+
(:workspace-folders db)))
1817

1918
(defn ^:private list-allowed-directories [_arguments db]
2019
(single-text-content
2120
(str "Allowed directories:\n"
2221
(string/join "\n"
2322
(map (comp shared/uri->filename :uri) (:workspace-folders db))))))
2423

24+
(defn ^:private invalid-arguments [arguments validator]
25+
(first (keep (fn [[key pred error-msg]]
26+
(let [value (get arguments key)]
27+
(when-not (pred value)
28+
(single-text-content (string/replace error-msg (str "$" key) value)))))
29+
validator)))
30+
2531
(defn ^:private list-directory [arguments db]
26-
(let [path (fs/canonicalize (get arguments "path"))]
27-
(or (not-allowed-path path db)
32+
(let [path (delay (fs/canonicalize (get arguments "path")))]
33+
(or (invalid-arguments arguments [["path" fs/regular-file? "$path is not a valid path"]
34+
["path" (partial allowed-path? db) "Access denied - path $path outside allowed directories"]])
2835
(single-text-content
2936
(reduce
3037
(fn [out path]
@@ -33,7 +40,7 @@
3340
(if (fs/directory? path) "DIR" "FILE")
3441
path)))
3542
""
36-
(fs/list-dir path))))))
43+
(fs/list-dir @path))))))
3744

3845
(def definitions
3946
{"list_allowed_directories"

test/eca/features/tools/filesystem_test.clj

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
(ns eca.features.tools.filesystem-test
22
(:require
33
[babashka.fs :as fs]
4-
[clojure.string :as string]
54
[clojure.test :refer [deftest is testing]]
65
[eca.features.tools.filesystem :as f.tools.filesystem]
76
[eca.test-helper :as h]
@@ -18,12 +17,23 @@
1817
{:workspace-folders [{:uri (h/file-uri "file:///foo/bar/baz") :name "baz"}]}))))
1918

2019
(deftest list-directory-test
21-
(testing "unallowed dir"
20+
(testing "Invalid path"
2221
(is (match?
2322
{:contents [{:type :text
2423
:error false
25-
:content "Access denied - path outside workspace root, call list_allowed_dirs first"}]}
26-
(with-redefs [fs/canonicalize (constantly (h/file-path "/foo/qux"))]
24+
:content "/foo/qux is not a valid path"}]}
25+
(with-redefs [fs/canonicalize (constantly (h/file-path "/foo/qux"))
26+
fs/regular-file? (constantly false)]
27+
((get-in f.tools.filesystem/definitions ["list_directory" :handler])
28+
{"path" (h/file-path "/foo/qux")}
29+
{:workspace-folders [{:uri (h/file-uri "file:///foo/bar/baz") :name "baz"}]})))))
30+
(testing "Unallowed dir"
31+
(is (match?
32+
{:contents [{:type :text
33+
:error false
34+
:content "Access denied - path /foo/qux outside allowed directories"}]}
35+
(with-redefs [fs/canonicalize (constantly (h/file-path "/foo/qux"))
36+
fs/regular-file? (constantly true)]
2737
((get-in f.tools.filesystem/definitions ["list_directory" :handler])
2838
{"path" (h/file-path "/foo/qux")}
2939
{:workspace-folders [{:uri (h/file-uri "file:///foo/bar/baz") :name "baz"}]})))))
@@ -35,7 +45,8 @@
3545
"[DIR] %s\n")
3646
(h/file-path "/foo/bar/baz/some.clj")
3747
(h/file-path "/foo/bar/baz/qux"))}]}
38-
(with-redefs [fs/starts-with? (constantly true)
48+
(with-redefs [fs/regular-file? (constantly true)
49+
fs/starts-with? (constantly true)
3950
fs/list-dir (constantly [(fs/path (h/file-path "/foo/bar/baz/some.clj"))
4051
(fs/path (h/file-path "/foo/bar/baz/qux"))])
4152
fs/directory? (fn [path] (not (string/ends-with? (str path) ".clj")))

0 commit comments

Comments
 (0)