diff --git a/xpcom/base/ErrorNames.cpp b/xpcom/base/ErrorNames.cpp new file mode 100644 index 000000000000..b9bc553d9bf4 --- /dev/null +++ b/xpcom/base/ErrorNames.cpp @@ -0,0 +1,83 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/ArrayUtils.h" +#include "mozilla/ErrorNames.h" +#include "nsString.h" +#include "prerror.h" + +namespace { + +struct ErrorEntry +{ + nsresult value; + const char * name; +}; + +#undef ERROR +#define ERROR(key, val) {key, #key} + +const ErrorEntry errors[] = { + #include "ErrorList.h" +}; + +#undef ERROR + +} // unnamed namespace + +namespace mozilla { + +void +GetErrorName(nsresult rv, nsACString& name) +{ + for (size_t i = 0; i < ArrayLength(errors); ++i) { + if (errors[i].value == rv) { + name.AssignASCII(errors[i].name); + return; + } + } + + bool isSecurityError = NS_ERROR_GET_MODULE(rv) == NS_ERROR_MODULE_SECURITY; + + // NS_ERROR_MODULE_SECURITY is the only module that is "allowed" to + // synthesize nsresult error codes that are not listed in ErrorList.h. (The + // NS_ERROR_MODULE_SECURITY error codes are synthesized from NSPR error + // codes.) + MOZ_ASSERT(isSecurityError); + + name.AssignASCII(NS_SUCCEEDED(rv) ? "NS_ERROR_GENERATE_SUCCESS(" + : "NS_ERROR_GENERATE_FAILURE("); + + if (isSecurityError) { + name.AppendASCII("NS_ERROR_MODULE_SECURITY"); + } else { + // This should never happen given the assertion above, so we don't bother + // trying to print a symbolic name for the module here. + name.AppendInt(NS_ERROR_GET_MODULE(rv)); + } + + name.AppendASCII(", "); + + const char * nsprName = nullptr; + if (isSecurityError) { + // Invert the logic from NSSErrorsService::GetXPCOMFromNSSError + PRErrorCode nsprCode + = -1 * static_cast(NS_ERROR_GET_CODE(rv)); + nsprName = PR_ErrorToName(nsprCode); + + // All NSPR error codes defined by NSPR or NSS should have a name mapping. + MOZ_ASSERT(nsprName); + } + + if (nsprName) { + name.AppendASCII(nsprName); + } else { + name.AppendInt(NS_ERROR_GET_CODE(rv)); + } + + name.AppendASCII(")"); +} + +} // namespace mozilla diff --git a/xpcom/base/ErrorNames.h b/xpcom/base/ErrorNames.h new file mode 100644 index 000000000000..1862c0f6791a --- /dev/null +++ b/xpcom/base/ErrorNames.h @@ -0,0 +1,24 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_ErrorNames_h +#define mozilla_ErrorNames_h + +#include "nsError.h" + +class nsACString; + +namespace mozilla { + +// Maps the given nsresult to its symbolic name. For example, +// GetErrorName(NS_OK, name) will result in name == "NS_OK". +// When the symbolic name is unknown, name will be of the form +// "NS_ERROR_GENERATE_SUCCESS(, )" or +// "NS_ERROR_GENERATE_FAILURE(, )". +void GetErrorName(nsresult rv, nsACString& name); + +} + +#endif // mozilla_ErrorNames_h diff --git a/xpcom/base/moz.build b/xpcom/base/moz.build index 8c49542465d2..e600314098a0 100644 --- a/xpcom/base/moz.build +++ b/xpcom/base/moz.build @@ -76,6 +76,7 @@ EXPORTS.mozilla += [ 'CountingAllocatorBase.h', 'CycleCollectedJSRuntime.h', 'Debug.h', + 'ErrorNames.h', 'LinuxUtils.h', 'nsMemoryInfoDumper.h', 'StackWalk.h', @@ -97,6 +98,7 @@ UNIFIED_SOURCES += [ 'ClearOnShutdown.cpp', 'CycleCollectedJSRuntime.cpp', 'Debug.cpp', + 'ErrorNames.cpp', 'nsConsoleMessage.cpp', 'nsConsoleService.cpp', 'nsCycleCollector.cpp',