1 // Copyright 2015 The Weave Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/utils.h"
6 
7 #include <base/bind_helpers.h>
8 #include <base/json/json_reader.h>
9 
10 #include "src/json_error_codes.h"
11 
12 namespace weave {
13 
14 namespace {
15 
16 // Truncates a string if it is too long. Used for error reporting with really
17 // long JSON strings.
LimitString(const std::string & text,size_t max_len)18 std::string LimitString(const std::string& text, size_t max_len) {
19   if (text.size() <= max_len)
20     return text;
21   return text.substr(0, max_len - 3) + "...";
22 }
23 
24 const size_t kMaxStrLen = 1700;  // Log messages are limited to 2000 chars.
25 
26 const char kErrorCodeKey[] = "code";
27 const char kErrorMessageKey[] = "message";
28 
29 }  // anonymous namespace
30 
31 namespace errors {
32 const char kSchemaError[] = "schema_error";
33 const char kInvalidCategoryError[] = "invalid_category";
34 const char kInvalidPackageError[] = "invalid_package";
35 }  // namespace errors
36 
LoadJsonDict(const std::string & json_string,ErrorPtr * error)37 std::unique_ptr<base::DictionaryValue> LoadJsonDict(
38     const std::string& json_string,
39     ErrorPtr* error) {
40   std::unique_ptr<base::DictionaryValue> result;
41   std::string error_message;
42   auto value = base::JSONReader::ReadAndReturnError(
43       json_string, base::JSON_PARSE_RFC, nullptr, &error_message);
44   if (!value) {
45     Error::AddToPrintf(error, FROM_HERE, errors::json::kParseError,
46                        "Error parsing JSON string '%s' (%zu): %s",
47                        LimitString(json_string, kMaxStrLen).c_str(),
48                        json_string.size(), error_message.c_str());
49     return result;
50   }
51   base::DictionaryValue* dict_value = nullptr;
52   if (!value->GetAsDictionary(&dict_value)) {
53     Error::AddToPrintf(error, FROM_HERE, errors::json::kObjectExpected,
54                        "JSON string '%s' is not a JSON object",
55                        LimitString(json_string, kMaxStrLen).c_str());
56     return result;
57   } else {
58     // |value| is now owned by |dict_value|.
59     base::IgnoreResult(value.release());
60   }
61   result.reset(dict_value);
62   return result;
63 }
64 
ErrorInfoToJson(const Error & error)65 std::unique_ptr<base::DictionaryValue> ErrorInfoToJson(const Error& error) {
66   std::unique_ptr<base::DictionaryValue> output{new base::DictionaryValue};
67   output->SetString(kErrorMessageKey, error.GetMessage());
68   output->SetString(kErrorCodeKey, error.GetCode());
69   return output;
70 }
71 
72 }  // namespace weave
73