void TfDiagnosticMgr::_ReportError(const TfError &err) { _ReentrancyGuard guard(&_reentrantGuard.local()); if (guard.ScopeWasReentered()) { return; } bool dispatchedToDelegate = false; { tbb::spin_rw_mutex::scoped_lock lock(_delegatesMutex, /*writer=*/false); for (auto const& delegate : _delegates) { if (delegate) { delegate->IssueError(err); } } dispatchedToDelegate = !_delegates.empty(); } if (!dispatchedToDelegate && !err.GetQuiet()) { _PrintDiagnostic(stderr, err.GetDiagnosticCode(), err.GetContext(), err.GetCommentary(), err._info); } }
void TfDiagnosticMgr::_ReportError(const TfError &err) { const bool isMainThread = ArchIsMainThread(); if (isMainThread && _delegate) { _delegate->IssueError(err); } else if (!err.GetQuiet()) { _PrintDiagnostic(stderr, err.GetDiagnosticCode(), err.GetContext(), err.GetCommentary(), err._data->_info); } if (isMainThread) TfDiagnosticNotice::IssuedError(err).Send(TfCreateWeakPtr(this)); }
static bool Test_TfError() { TfErrorMark m; size_t lineNum; m.SetMark(); TF_AXIOM(m.IsClean()); m.SetMark(); TF_ERROR(SMALL, "small error"); lineNum = __LINE__ - 1; TF_AXIOM(!m.IsClean()); TfErrorMark::Iterator i = m.GetBegin(); TF_AXIOM(i == TfDiagnosticMgr::GetInstance().GetErrorBegin()); TfError e = *i; TF_AXIOM(e.GetSourceFileName() == BUILD_COMPONENT_SRC_PREFIX __FILE__); TF_AXIOM(e.GetSourceLineNumber() == lineNum); TF_AXIOM(e.GetCommentary() == "small error"); TF_AXIOM(e.GetErrorCode() == SMALL); TF_AXIOM(e.GetErrorCodeAsString() == "SMALL"); TF_AXIOM(e.GetInfo<int>() == NULL); e.AugmentCommentary("augment"); TF_AXIOM(e.GetCommentary() == "small error\naugment"); i = TfDiagnosticMgr::GetInstance().EraseError(i); TF_AXIOM(i == TfDiagnosticMgr::GetInstance().GetErrorEnd()); m.SetMark(); TF_ERROR(1, MEDIUM, "medium error"); TF_ERROR(2, LARGE, "large error"); i = m.GetBegin(); TF_AXIOM(i == TfDiagnosticMgr::GetInstance().GetErrorBegin()); e = *i; TF_AXIOM(e.GetErrorCode() == MEDIUM); TF_AXIOM(*e.GetInfo<int>() == 1); ++i; TF_AXIOM(i != TfDiagnosticMgr::GetInstance().GetErrorEnd()); e = *i; TF_AXIOM(e.GetErrorCode() == LARGE); TF_AXIOM(*e.GetInfo<int>() == 2); m.Clear(); TF_AXIOM(m.IsClean()); TF_VERIFY(m.IsClean()); TF_AXIOM(TF_VERIFY(m.IsClean())); TF_CODING_ERROR("test error"); // It should be the case that m is not clean. TF_AXIOM(TF_VERIFY(not m.IsClean())); // It should not be the case that m is clean. TF_AXIOM(not TF_VERIFY(m.IsClean())); TF_AXIOM(not TF_VERIFY(m.IsClean(), "With a %s", "message.")); // Should issue a failed expect error. TF_VERIFY(m.IsClean()); m.Clear(); // Arbitrary info. std::string info("String containing arbitrary information."); // Issue a few different variations of errors. m.SetMark(); string errString = "Error!"; TF_CODING_ERROR("Coding error"); TF_CODING_ERROR("Coding error %d", 1); TF_CODING_ERROR(errString); TF_RUNTIME_ERROR("Runtime error"); TF_RUNTIME_ERROR("Runtime error %d", 1); TF_RUNTIME_ERROR(errString); TF_ERROR(SMALL, "const char *"); TF_ERROR(SMALL, "const char *, %s", "..."); TF_ERROR(SMALL, errString); TF_ERROR(info, MEDIUM, "const char *"); TF_ERROR(info, MEDIUM, "const char *, %s", "..."); TF_ERROR(info, MEDIUM, errString); TF_AXIOM(not m.IsClean()); m.Clear(); // Issue a few different warnings. string warningString = "Warning!"; TF_WARN("const char *"); TF_WARN("const char *, %s", "..."); TF_WARN(warningString); TF_WARN(SMALL, "const char *"); TF_WARN(SMALL, "const char *, %s", "..."); TF_WARN(SMALL, warningString); TF_WARN(info, MEDIUM, "const char *"); TF_WARN(info, MEDIUM, "const char *, %s", "..."); TF_WARN(info, MEDIUM, warningString); // Issue a few different status messages. string statusString = "Status"; TF_STATUS("const char *"); TF_STATUS("const char *, %s", "..."); TF_STATUS(statusString); TF_STATUS(SMALL, "const char *"); TF_STATUS(SMALL, "const char *, %s", "..."); TF_STATUS(SMALL, statusString); TF_STATUS(info, MEDIUM, "const char *"); TF_STATUS(info, MEDIUM, "const char *, %s", "..."); TF_STATUS(info, MEDIUM, statusString); return true; }