Repository: iterative/dvc

Issue:
Incorrect error message when importing to non-existent folder
## Setup
dvc 0.84.0
Mac, installation via conda

## Problem
When importing a file from a git repo into a subdirectory in the current repo, dvc fails with an incorrect error message if the subdirectory does not exist. 

To demonstrate this problem, run the following:

```
## Setup a git repo to import from
mkdir source_repo
cd source_repo
git init
echo Some code > code.txt
git add .
git commit -m "Save some code to this demo repo"

## setup a DVC repo to import from the previous
cd -
mkdir import_repo
cd import_repo
git init
dvc init
git add .
git commit -m "This is a dvc repo that will import some code"

echo --------------------------
echo The next command will fail with an incorrect error message
echo --------------------------
read -rsp $'Press any key to continue...\n' -n1 key

## Attempt an import which will fail
# This command will fail:
dvc import -o some_dir/code.txt ../source_repo code.txt

mkdir some_dir

echo --------------------------
echo Now we have made the output directory, it will succeed
echo --------------------------
read -rsp $'Press any key to continue...\n' -n1 key

dvc import -o some_dir/code.txt ../source_repo code.txt
```

## Expected behavior
Error message stating that the output directory does not exist

## Actual behaviour
This error message:
```
ERROR: failed to import 'code.txt' from '../source_repo'. - The path 'code.txt' does not exist in the target repository '../source_repo' neither as an output nor a git-handled file.
```
Note that `code.txt` does exist and is committed to git. DVC successfully imports it if the subdirectory `some_dir` exists. 




Discussion:
Hi @charlesbaynham ! Thanks for reporting this issue! I am able to reproduce a similar issue with:
```
dvc import https://github.com/iterative/dvc scripts/innosetup/dvc.ico -o nonexistent_dir/dvc.ico
```
But `dvc get` seems to work fine with the same arguments, so some of our logic has diverged there. 
Looking into it...
@charlesbaynham We've done some adjustments to `import` logic and now I'm getting a different error from your script:
```
+ dvc import -o some_dir/code.txt ../source_repo code.txt                                                                                              
ERROR: failed to import 'code.txt' from '../source_repo'. - stage working or file path '/home/efiop/git/dvc/myrepo/import_repo/some_dir' does not exist
```
which has a typo (will send a fix soon), but is now pointing out that the directory doesn't, which is expected behaviour now. 
Thank you @efiop ! DVC is great by the way, I'm enjoying using it a lot

Resolving patch:
diff --git a/dvc/stage.py b/dvc/stage.py
--- a/dvc/stage.py
+++ b/dvc/stage.py
@@ -75,21 +75,15 @@ class StageFileBadNameError(DvcException):
 
 
 class StagePathOutsideError(DvcException):
-    def __init__(self, path):
-        msg = "stage working or file path '{}' is outside of DVC repo"
-        super().__init__(msg.format(path))
+    pass
 
 
 class StagePathNotFoundError(DvcException):
-    def __init__(self, path):
-        msg = "stage working or file path '{}' does not exist"
-        super().__init__(msg.format(path))
+    pass
 
 
 class StagePathNotDirectoryError(DvcException):
-    def __init__(self, path):
-        msg = "stage working or file path '{}' is not directory"
-        super().__init__(msg.format(path))
+    pass
 
 
 class StageCommitError(DvcException):
@@ -442,19 +436,28 @@ def _stage_fname(cls, outs, add):
         return fname
 
     @staticmethod
-    def _check_stage_path(repo, path):
+    def _check_stage_path(repo, path, is_wdir=False):
         assert repo is not None
 
+        error_msg = "{wdir_or_path} '{path}' {{}}".format(
+            wdir_or_path="stage working dir" if is_wdir else "file path",
+            path=path,
+        )
+
         real_path = os.path.realpath(path)
         if not os.path.exists(real_path):
-            raise StagePathNotFoundError(path)
+            raise StagePathNotFoundError(error_msg.format("does not exist"))
 
         if not os.path.isdir(real_path):
-            raise StagePathNotDirectoryError(path)
+            raise StagePathNotDirectoryError(
+                error_msg.format("is not directory")
+            )
 
         proj_dir = os.path.realpath(repo.root_dir)
         if real_path != proj_dir and not path_isin(real_path, proj_dir):
-            raise StagePathOutsideError(path)
+            raise StagePathOutsideError(
+                error_msg.format("is outside of DVC repo")
+            )
 
     @property
     def is_cached(self):
@@ -557,7 +560,7 @@ def create(repo, accompany_outs=False, **kwargs):
         else:
             path = os.path.abspath(fname)
 
-        Stage._check_stage_path(repo, wdir)
+        Stage._check_stage_path(repo, wdir, is_wdir=kwargs.get("wdir"))
         Stage._check_stage_path(repo, os.path.dirname(path))
 
         stage.wdir = wdir


Test patch: