Repository: conan-io/conan

Issue:
Know who is requiring a missing dependency
When the command ``conan info`` or ``conan install`` fails, because there is a missing dependency, it is not possible to know who required it, and that can be specially difficult for complex dependency graphs, using version ranges, etc.






Discussion:
Btw, the json output of ``conan install`` doesn't help much:

```json
{"installed": [{"packages": [], 
    "recipe": {"error": null, 
        "id": "Poco/1.9.0@pocoproject/stable"}}, 
        {"packages": [], 
    "recipe": {"error": null, 
        "id": "OpenSSL/1.0.2o@conan/stable"}}, 
        {"packages": [], 
    "recipe": {"error": {"remote": null, 
        "type": "missing", 
        "description": "Unable to find 'zlib/1.2.12@conan/stable' in remotes"}, 
        "remote": null, 
        "dependency": true, 
        "cache": false, 
        "downloaded": false, 
        "time": "2018-07-12T15:03:58.843000", 
        "id": "zlib/1.2.12@conan/stable"}}], 
"error": true}
```

Resolving patch:
diff --git a/conans/client/graph/graph_builder.py b/conans/client/graph/graph_builder.py
--- a/conans/client/graph/graph_builder.py
+++ b/conans/client/graph/graph_builder.py
@@ -204,8 +204,14 @@ def _create_new_node(self, current_node, dep_graph, requirement, public_deps, na
             recipe_status = RECIPE_WORKSPACE
             remote = WORKSPACE_FILE
         else:
-            result = self._proxy.get_recipe(requirement.conan_reference,
-                                            check_updates, update, remote_name)
+            try:
+                result = self._proxy.get_recipe(requirement.conan_reference,
+                                                check_updates, update, remote_name)
+            except ConanException as e:
+                base_ref = str(current_node.conan_ref or "PROJECT")
+                self._output.error("Failed requirement '%s' from '%s'" % (requirement.conan_reference,
+                                                                          base_ref))
+                raise e
             conanfile_path, recipe_status, remote = result
 
         output = ScopedOutput(str(requirement.conan_reference), self._output)
diff --git a/conans/client/graph/range_resolver.py b/conans/client/graph/range_resolver.py
--- a/conans/client/graph/range_resolver.py
+++ b/conans/client/graph/range_resolver.py
@@ -62,8 +62,9 @@ def resolve(self, require, base_conanref, update, remote_name):
                                  % (version_range, base_conanref, str(resolved)))
             require.conan_reference = resolved
         else:
-            raise ConanException("The version in '%s' from requirement '%s' could not be resolved"
-                                 % (version_range, require))
+            base_conanref = base_conanref or "PROJECT"
+            raise ConanException("Version range '%s' from requirement '%s' required by '%s' "
+                                 "could not be resolved" % (version_range, require, base_conanref))
 
     def _resolve_local(self, search_ref, version_range):
         local_found = search_recipes(self._client_cache, search_ref)


Test patch:
diff --git a/conans/test/command/install_test.py b/conans/test/command/install_test.py
--- a/conans/test/command/install_test.py
+++ b/conans/test/command/install_test.py
@@ -451,6 +451,8 @@ class Pkg(ConanFile):
         client.run("remote remove_ref Hello/0.1@lasote/stable")
         error = client.run("install Hello/0.1@lasote/stable", ignore_error=True)
         self.assertTrue(error)
+        self.assertIn("ERROR: Failed requirement 'Hello/0.1@lasote/stable' from 'PROJECT'",
+                      client.out)
         self.assertIn("ERROR: Unable to find 'Hello/0.1@lasote/stable' in remotes",
                       client.out)