1// Copyright (c) 2012 The Chromium 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 "sync/api/sync_error.h"
6
7#include <ostream>
8
9#include "base/location.h"
10#include "base/logging.h"
11#include "sync/internal_api/public/base/model_type.h"
12
13namespace syncer {
14
15SyncError::SyncError() {
16  Clear();
17}
18
19SyncError::SyncError(const tracked_objects::Location& location,
20                     ErrorType error_type,
21                     const std::string& message,
22                     ModelType model_type) {
23  DCHECK(error_type != UNSET);
24  Init(location, message, model_type, error_type);
25  PrintLogError();
26}
27
28SyncError::SyncError(const SyncError& other) {
29  Copy(other);
30}
31
32SyncError::~SyncError() {
33}
34
35SyncError& SyncError::operator=(const SyncError& other) {
36  if (this == &other) {
37    return *this;
38  }
39  Copy(other);
40  return *this;
41}
42
43void SyncError::Copy(const SyncError& other) {
44  if (other.IsSet()) {
45    Init(other.location(),
46         other.message(),
47         other.model_type(),
48         other.error_type());
49  } else {
50    Clear();
51  }
52}
53
54void SyncError::Clear() {
55  location_.reset();
56  message_ = std::string();
57  model_type_ = UNSPECIFIED;
58  error_type_ = UNSET;
59}
60
61void SyncError::Reset(const tracked_objects::Location& location,
62                      const std::string& message,
63                      ModelType model_type) {
64  Init(location, message, model_type, DATATYPE_ERROR);
65  PrintLogError();
66}
67
68void SyncError::Init(const tracked_objects::Location& location,
69                     const std::string& message,
70                     ModelType model_type,
71                     ErrorType error_type) {
72  location_.reset(new tracked_objects::Location(location));
73  message_ = message;
74  model_type_ = model_type;
75  error_type_ = error_type;
76}
77
78bool SyncError::IsSet() const {
79  return error_type_ != UNSET;
80}
81
82
83const tracked_objects::Location& SyncError::location() const {
84  CHECK(IsSet());
85  return *location_;
86}
87
88const std::string& SyncError::message() const {
89  CHECK(IsSet());
90  return message_;
91}
92
93ModelType SyncError::model_type() const {
94  CHECK(IsSet());
95  return model_type_;
96}
97
98SyncError::ErrorType SyncError::error_type() const {
99  CHECK(IsSet());
100  return error_type_;
101}
102
103SyncError::Severity SyncError::GetSeverity() const {
104  switch (error_type_) {
105    case UNREADY_ERROR:
106    case DATATYPE_POLICY_ERROR:
107      return SYNC_ERROR_SEVERITY_INFO;
108    default:
109      return SYNC_ERROR_SEVERITY_ERROR;
110  }
111}
112
113std::string SyncError::GetMessagePrefix() const {
114  std::string type_message;
115  switch (error_type_) {
116    case UNRECOVERABLE_ERROR:
117      type_message = "unrecoverable error was encountered: ";
118      break;
119    case DATATYPE_ERROR:
120      type_message = "datatype error was encountered: ";
121      break;
122    case PERSISTENCE_ERROR:
123      type_message = "persistence error was encountered: ";
124      break;
125    case CRYPTO_ERROR:
126      type_message = "cryptographer error was encountered: ";
127      break;
128    case UNREADY_ERROR:
129      type_message = "unready error was encountered: ";
130      break;
131    case DATATYPE_POLICY_ERROR:
132      type_message = "disabled due to configuration constraints: ";
133      break;
134    case UNSET:
135      NOTREACHED() << "Invalid error type";
136      break;
137  }
138  return type_message;
139}
140
141std::string SyncError::ToString() const {
142  if (!IsSet()) {
143    return std::string();
144  }
145  return location_->ToString() + ", " + ModelTypeToString(model_type_) +
146      " " + GetMessagePrefix() + message_;
147}
148
149void SyncError::PrintLogError() const {
150  logging::LogSeverity logSeverity =
151      (GetSeverity() == SYNC_ERROR_SEVERITY_INFO)
152          ? logging::LOG_VERBOSE : logging::LOG_ERROR;
153
154  LAZY_STREAM(logging::LogMessage(location_->file_name(),
155                                  location_->line_number(),
156                                  logSeverity).stream(),
157              logSeverity >= ::logging::GetMinLogLevel())
158      << ModelTypeToString(model_type_) << " "
159      << GetMessagePrefix() << message_;
160}
161
162void PrintTo(const SyncError& sync_error, std::ostream* os) {
163  *os << sync_error.ToString();
164}
165
166}  // namespace syncer
167