mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2026-06-20 01:17:49 +02:00
Do not retry fatal errors.
There is some evidence that retrying fatal errors, especially out of memory errors, may cause lockups. It makes sense to report fatal errors as quickly as possible and bypass retries. This may or not fix the lockup issue but it is worth doing either way. For now, the only fatal errors will be AssertError and MemoryError.
This commit is contained in:
+13
-11
@@ -75,6 +75,19 @@
|
||||
<p>Add backup LSNs to <cmd>info</cmd> command output.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<commit subject="Improve protocol module error test for protocolClientFree()."/>
|
||||
<commit subject="Use normal error for protocol module error retry test."/>
|
||||
<commit subject="Do not retry fatal errors."/>
|
||||
|
||||
<release-item-contributor-list>
|
||||
<release-item-contributor id="david.steele"/>
|
||||
<release-item-reviewer id="reid.thompson"/>
|
||||
</release-item-contributor-list>
|
||||
|
||||
<p>Do not retry fatal errors.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<github-pull-request id="1611"/>
|
||||
|
||||
@@ -125,17 +138,6 @@
|
||||
<p>Improve small file support.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<commit subject="Improve protocol module error test for protocolClientFree()."/>
|
||||
<commit subject="Use normal error for protocol module error retry test."/>
|
||||
|
||||
<release-item-contributor-list>
|
||||
<release-item-contributor id="david.steele"/>
|
||||
</release-item-contributor-list>
|
||||
|
||||
<p>Do not retry fatal errors.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<commit subject="Add ioBufferReadNewOpen() and ioBufferWriteNewOpen()."/>
|
||||
<commit subject="Refactor lock code."/>
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
# Definitions for all C errors, auto-generated to src/common/error.auto.c/h.
|
||||
|
||||
# Errors in the code that it should not be possible for the user to encounter -- i.e., a likely bug
|
||||
assert: 25
|
||||
assert:
|
||||
code: 25
|
||||
fatal: true
|
||||
|
||||
checksum: 26
|
||||
config: 27
|
||||
@@ -73,7 +75,9 @@ path-exists: 92
|
||||
file-exists: 93
|
||||
|
||||
# Memory allocation failed
|
||||
memory: 94
|
||||
memory:
|
||||
code: 94
|
||||
fatal: true
|
||||
|
||||
crypto: 95
|
||||
param-invalid: 96
|
||||
|
||||
+35
-4
@@ -25,7 +25,8 @@ Parse error list
|
||||
typedef struct BldErrErrorRaw
|
||||
{
|
||||
const String *const name; // See BldErrError for comments
|
||||
unsigned int code;
|
||||
unsigned int code;
|
||||
bool fatal;
|
||||
} BldErrErrorRaw;
|
||||
|
||||
static List *
|
||||
@@ -48,9 +49,38 @@ bldErrParseErrorList(Yaml *const yaml)
|
||||
.name = err.value,
|
||||
};
|
||||
|
||||
// Parse error code and check that it is valid
|
||||
YamlEvent errVal = yamlEventNextCheck(yaml, yamlEventTypeScalar);
|
||||
errRaw.code = cvtZToUInt(strZ(errVal.value));
|
||||
YamlEvent errDef = yamlEventNext(yaml);
|
||||
|
||||
// If scalar then it is an error code
|
||||
if (errDef.type == yamlEventTypeScalar)
|
||||
{
|
||||
errRaw.code = cvtZToUInt(strZ(errDef.value));
|
||||
}
|
||||
// Else there may be multiple definitions
|
||||
else
|
||||
{
|
||||
yamlEventCheck(errDef, yamlEventTypeMapBegin);
|
||||
YamlEvent errDef = yamlEventNextCheck(yaml, yamlEventTypeScalar);
|
||||
|
||||
do
|
||||
{
|
||||
YamlEvent errDefVal = yamlEventNextCheck(yaml, yamlEventTypeScalar);
|
||||
|
||||
if (strEqZ(errDef.value, "code"))
|
||||
{
|
||||
errRaw.code = cvtZToUInt(strZ(errDefVal.value));
|
||||
}
|
||||
else if (strEqZ(errDef.value, "fatal"))
|
||||
{
|
||||
errRaw.fatal = yamlBoolParse(errDefVal);
|
||||
}
|
||||
else
|
||||
THROW_FMT(FormatError, "unknown error definition '%s'", strZ(errDef.value));
|
||||
|
||||
errDef = yamlEventNext(yaml);
|
||||
}
|
||||
while (errDef.type != yamlEventTypeMapEnd);
|
||||
}
|
||||
|
||||
if (errRaw.code < ERROR_CODE_MIN || errRaw.code > ERROR_CODE_MAX)
|
||||
{
|
||||
@@ -68,6 +98,7 @@ bldErrParseErrorList(Yaml *const yaml)
|
||||
{
|
||||
.name = strDup(errRaw.name),
|
||||
.code = errRaw.code,
|
||||
.fatal = errRaw.fatal,
|
||||
});
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
|
||||
@@ -13,6 +13,7 @@ typedef struct BldErrError
|
||||
{
|
||||
const String *const name; // Name
|
||||
const unsigned int code; // Code
|
||||
const bool fatal; // Is the error fatal?
|
||||
} BldErrError;
|
||||
|
||||
typedef struct BldErr
|
||||
|
||||
@@ -6,6 +6,7 @@ Render Error Data
|
||||
#include <ctype.h>
|
||||
|
||||
#include "common/log.h"
|
||||
#include "common/type/convert.h"
|
||||
#include "storage/posix/storage.h"
|
||||
|
||||
#include "build/common/render.h"
|
||||
@@ -101,7 +102,9 @@ bldErrRenderErrorAutoC(const Storage *const storageRepo, const BldErr bldErr)
|
||||
{
|
||||
const BldErrError *const err = lstGet(bldErr.errList, errIdx);
|
||||
|
||||
strCatFmt(error, "ERROR_DEFINE(%3u, %s, RuntimeError);\n", err->code, strZ(bldErrName(err->name)));
|
||||
strCatFmt(
|
||||
error, "ERROR_DEFINE(%3u, %s, %s, RuntimeError);\n", err->code, strZ(bldErrName(err->name)),
|
||||
cvtBoolToConstZ(err->fatal));
|
||||
}
|
||||
|
||||
// Error type array
|
||||
|
||||
@@ -628,7 +628,7 @@ cmdArchivePushAsync(void)
|
||||
}
|
||||
}
|
||||
// On any global error write a single error file to cover all unprocessed files
|
||||
CATCH_ANY()
|
||||
CATCH_FATAL()
|
||||
{
|
||||
archiveAsyncStatusErrorWrite(archiveModePush, NULL, errorCode(), STR(errorMessage()));
|
||||
RETHROW();
|
||||
|
||||
+83
-83
@@ -7,89 +7,89 @@ Automatically generated by 'make build-error' -- do not modify directly.
|
||||
/***********************************************************************************************************************************
|
||||
Error type definitions
|
||||
***********************************************************************************************************************************/
|
||||
ERROR_DEFINE( 25, AssertError, RuntimeError);
|
||||
ERROR_DEFINE( 26, ChecksumError, RuntimeError);
|
||||
ERROR_DEFINE( 27, ConfigError, RuntimeError);
|
||||
ERROR_DEFINE( 28, FileInvalidError, RuntimeError);
|
||||
ERROR_DEFINE( 29, FormatError, RuntimeError);
|
||||
ERROR_DEFINE( 30, CommandRequiredError, RuntimeError);
|
||||
ERROR_DEFINE( 31, OptionInvalidError, RuntimeError);
|
||||
ERROR_DEFINE( 32, OptionInvalidValueError, RuntimeError);
|
||||
ERROR_DEFINE( 33, OptionInvalidRangeError, RuntimeError);
|
||||
ERROR_DEFINE( 34, OptionInvalidPairError, RuntimeError);
|
||||
ERROR_DEFINE( 35, OptionDuplicateKeyError, RuntimeError);
|
||||
ERROR_DEFINE( 36, OptionNegateError, RuntimeError);
|
||||
ERROR_DEFINE( 37, OptionRequiredError, RuntimeError);
|
||||
ERROR_DEFINE( 38, PgRunningError, RuntimeError);
|
||||
ERROR_DEFINE( 39, ProtocolError, RuntimeError);
|
||||
ERROR_DEFINE( 40, PathNotEmptyError, RuntimeError);
|
||||
ERROR_DEFINE( 41, FileOpenError, RuntimeError);
|
||||
ERROR_DEFINE( 42, FileReadError, RuntimeError);
|
||||
ERROR_DEFINE( 43, ParamRequiredError, RuntimeError);
|
||||
ERROR_DEFINE( 44, ArchiveMismatchError, RuntimeError);
|
||||
ERROR_DEFINE( 45, ArchiveDuplicateError, RuntimeError);
|
||||
ERROR_DEFINE( 46, VersionNotSupportedError, RuntimeError);
|
||||
ERROR_DEFINE( 47, PathCreateError, RuntimeError);
|
||||
ERROR_DEFINE( 48, CommandInvalidError, RuntimeError);
|
||||
ERROR_DEFINE( 49, HostConnectError, RuntimeError);
|
||||
ERROR_DEFINE( 50, LockAcquireError, RuntimeError);
|
||||
ERROR_DEFINE( 51, BackupMismatchError, RuntimeError);
|
||||
ERROR_DEFINE( 52, FileSyncError, RuntimeError);
|
||||
ERROR_DEFINE( 53, PathOpenError, RuntimeError);
|
||||
ERROR_DEFINE( 54, PathSyncError, RuntimeError);
|
||||
ERROR_DEFINE( 55, FileMissingError, RuntimeError);
|
||||
ERROR_DEFINE( 56, DbConnectError, RuntimeError);
|
||||
ERROR_DEFINE( 57, DbQueryError, RuntimeError);
|
||||
ERROR_DEFINE( 58, DbMismatchError, RuntimeError);
|
||||
ERROR_DEFINE( 59, DbTimeoutError, RuntimeError);
|
||||
ERROR_DEFINE( 60, FileRemoveError, RuntimeError);
|
||||
ERROR_DEFINE( 61, PathRemoveError, RuntimeError);
|
||||
ERROR_DEFINE( 62, StopError, RuntimeError);
|
||||
ERROR_DEFINE( 63, TermError, RuntimeError);
|
||||
ERROR_DEFINE( 64, FileWriteError, RuntimeError);
|
||||
ERROR_DEFINE( 66, ProtocolTimeoutError, RuntimeError);
|
||||
ERROR_DEFINE( 67, FeatureNotSupportedError, RuntimeError);
|
||||
ERROR_DEFINE( 68, ArchiveCommandInvalidError, RuntimeError);
|
||||
ERROR_DEFINE( 69, LinkExpectedError, RuntimeError);
|
||||
ERROR_DEFINE( 70, LinkDestinationError, RuntimeError);
|
||||
ERROR_DEFINE( 72, HostInvalidError, RuntimeError);
|
||||
ERROR_DEFINE( 73, PathMissingError, RuntimeError);
|
||||
ERROR_DEFINE( 74, FileMoveError, RuntimeError);
|
||||
ERROR_DEFINE( 75, BackupSetInvalidError, RuntimeError);
|
||||
ERROR_DEFINE( 76, TablespaceMapError, RuntimeError);
|
||||
ERROR_DEFINE( 77, PathTypeError, RuntimeError);
|
||||
ERROR_DEFINE( 78, LinkMapError, RuntimeError);
|
||||
ERROR_DEFINE( 79, FileCloseError, RuntimeError);
|
||||
ERROR_DEFINE( 80, DbMissingError, RuntimeError);
|
||||
ERROR_DEFINE( 81, DbInvalidError, RuntimeError);
|
||||
ERROR_DEFINE( 82, ArchiveTimeoutError, RuntimeError);
|
||||
ERROR_DEFINE( 83, FileModeError, RuntimeError);
|
||||
ERROR_DEFINE( 84, OptionMultipleValueError, RuntimeError);
|
||||
ERROR_DEFINE( 85, ProtocolOutputRequiredError, RuntimeError);
|
||||
ERROR_DEFINE( 86, LinkOpenError, RuntimeError);
|
||||
ERROR_DEFINE( 87, ArchiveDisabledError, RuntimeError);
|
||||
ERROR_DEFINE( 88, FileOwnerError, RuntimeError);
|
||||
ERROR_DEFINE( 89, UserMissingError, RuntimeError);
|
||||
ERROR_DEFINE( 90, OptionCommandError, RuntimeError);
|
||||
ERROR_DEFINE( 91, GroupMissingError, RuntimeError);
|
||||
ERROR_DEFINE( 92, PathExistsError, RuntimeError);
|
||||
ERROR_DEFINE( 93, FileExistsError, RuntimeError);
|
||||
ERROR_DEFINE( 94, MemoryError, RuntimeError);
|
||||
ERROR_DEFINE( 95, CryptoError, RuntimeError);
|
||||
ERROR_DEFINE( 96, ParamInvalidError, RuntimeError);
|
||||
ERROR_DEFINE( 97, PathCloseError, RuntimeError);
|
||||
ERROR_DEFINE( 98, FileInfoError, RuntimeError);
|
||||
ERROR_DEFINE( 99, JsonFormatError, RuntimeError);
|
||||
ERROR_DEFINE(100, KernelError, RuntimeError);
|
||||
ERROR_DEFINE(101, ServiceError, RuntimeError);
|
||||
ERROR_DEFINE(102, ExecuteError, RuntimeError);
|
||||
ERROR_DEFINE(103, RepoInvalidError, RuntimeError);
|
||||
ERROR_DEFINE(104, CommandError, RuntimeError);
|
||||
ERROR_DEFINE(105, AccessError, RuntimeError);
|
||||
ERROR_DEFINE(122, RuntimeError, RuntimeError);
|
||||
ERROR_DEFINE(123, InvalidError, RuntimeError);
|
||||
ERROR_DEFINE(124, UnhandledError, RuntimeError);
|
||||
ERROR_DEFINE(125, UnknownError, RuntimeError);
|
||||
ERROR_DEFINE( 25, AssertError, true, RuntimeError);
|
||||
ERROR_DEFINE( 26, ChecksumError, false, RuntimeError);
|
||||
ERROR_DEFINE( 27, ConfigError, false, RuntimeError);
|
||||
ERROR_DEFINE( 28, FileInvalidError, false, RuntimeError);
|
||||
ERROR_DEFINE( 29, FormatError, false, RuntimeError);
|
||||
ERROR_DEFINE( 30, CommandRequiredError, false, RuntimeError);
|
||||
ERROR_DEFINE( 31, OptionInvalidError, false, RuntimeError);
|
||||
ERROR_DEFINE( 32, OptionInvalidValueError, false, RuntimeError);
|
||||
ERROR_DEFINE( 33, OptionInvalidRangeError, false, RuntimeError);
|
||||
ERROR_DEFINE( 34, OptionInvalidPairError, false, RuntimeError);
|
||||
ERROR_DEFINE( 35, OptionDuplicateKeyError, false, RuntimeError);
|
||||
ERROR_DEFINE( 36, OptionNegateError, false, RuntimeError);
|
||||
ERROR_DEFINE( 37, OptionRequiredError, false, RuntimeError);
|
||||
ERROR_DEFINE( 38, PgRunningError, false, RuntimeError);
|
||||
ERROR_DEFINE( 39, ProtocolError, false, RuntimeError);
|
||||
ERROR_DEFINE( 40, PathNotEmptyError, false, RuntimeError);
|
||||
ERROR_DEFINE( 41, FileOpenError, false, RuntimeError);
|
||||
ERROR_DEFINE( 42, FileReadError, false, RuntimeError);
|
||||
ERROR_DEFINE( 43, ParamRequiredError, false, RuntimeError);
|
||||
ERROR_DEFINE( 44, ArchiveMismatchError, false, RuntimeError);
|
||||
ERROR_DEFINE( 45, ArchiveDuplicateError, false, RuntimeError);
|
||||
ERROR_DEFINE( 46, VersionNotSupportedError, false, RuntimeError);
|
||||
ERROR_DEFINE( 47, PathCreateError, false, RuntimeError);
|
||||
ERROR_DEFINE( 48, CommandInvalidError, false, RuntimeError);
|
||||
ERROR_DEFINE( 49, HostConnectError, false, RuntimeError);
|
||||
ERROR_DEFINE( 50, LockAcquireError, false, RuntimeError);
|
||||
ERROR_DEFINE( 51, BackupMismatchError, false, RuntimeError);
|
||||
ERROR_DEFINE( 52, FileSyncError, false, RuntimeError);
|
||||
ERROR_DEFINE( 53, PathOpenError, false, RuntimeError);
|
||||
ERROR_DEFINE( 54, PathSyncError, false, RuntimeError);
|
||||
ERROR_DEFINE( 55, FileMissingError, false, RuntimeError);
|
||||
ERROR_DEFINE( 56, DbConnectError, false, RuntimeError);
|
||||
ERROR_DEFINE( 57, DbQueryError, false, RuntimeError);
|
||||
ERROR_DEFINE( 58, DbMismatchError, false, RuntimeError);
|
||||
ERROR_DEFINE( 59, DbTimeoutError, false, RuntimeError);
|
||||
ERROR_DEFINE( 60, FileRemoveError, false, RuntimeError);
|
||||
ERROR_DEFINE( 61, PathRemoveError, false, RuntimeError);
|
||||
ERROR_DEFINE( 62, StopError, false, RuntimeError);
|
||||
ERROR_DEFINE( 63, TermError, false, RuntimeError);
|
||||
ERROR_DEFINE( 64, FileWriteError, false, RuntimeError);
|
||||
ERROR_DEFINE( 66, ProtocolTimeoutError, false, RuntimeError);
|
||||
ERROR_DEFINE( 67, FeatureNotSupportedError, false, RuntimeError);
|
||||
ERROR_DEFINE( 68, ArchiveCommandInvalidError, false, RuntimeError);
|
||||
ERROR_DEFINE( 69, LinkExpectedError, false, RuntimeError);
|
||||
ERROR_DEFINE( 70, LinkDestinationError, false, RuntimeError);
|
||||
ERROR_DEFINE( 72, HostInvalidError, false, RuntimeError);
|
||||
ERROR_DEFINE( 73, PathMissingError, false, RuntimeError);
|
||||
ERROR_DEFINE( 74, FileMoveError, false, RuntimeError);
|
||||
ERROR_DEFINE( 75, BackupSetInvalidError, false, RuntimeError);
|
||||
ERROR_DEFINE( 76, TablespaceMapError, false, RuntimeError);
|
||||
ERROR_DEFINE( 77, PathTypeError, false, RuntimeError);
|
||||
ERROR_DEFINE( 78, LinkMapError, false, RuntimeError);
|
||||
ERROR_DEFINE( 79, FileCloseError, false, RuntimeError);
|
||||
ERROR_DEFINE( 80, DbMissingError, false, RuntimeError);
|
||||
ERROR_DEFINE( 81, DbInvalidError, false, RuntimeError);
|
||||
ERROR_DEFINE( 82, ArchiveTimeoutError, false, RuntimeError);
|
||||
ERROR_DEFINE( 83, FileModeError, false, RuntimeError);
|
||||
ERROR_DEFINE( 84, OptionMultipleValueError, false, RuntimeError);
|
||||
ERROR_DEFINE( 85, ProtocolOutputRequiredError, false, RuntimeError);
|
||||
ERROR_DEFINE( 86, LinkOpenError, false, RuntimeError);
|
||||
ERROR_DEFINE( 87, ArchiveDisabledError, false, RuntimeError);
|
||||
ERROR_DEFINE( 88, FileOwnerError, false, RuntimeError);
|
||||
ERROR_DEFINE( 89, UserMissingError, false, RuntimeError);
|
||||
ERROR_DEFINE( 90, OptionCommandError, false, RuntimeError);
|
||||
ERROR_DEFINE( 91, GroupMissingError, false, RuntimeError);
|
||||
ERROR_DEFINE( 92, PathExistsError, false, RuntimeError);
|
||||
ERROR_DEFINE( 93, FileExistsError, false, RuntimeError);
|
||||
ERROR_DEFINE( 94, MemoryError, true, RuntimeError);
|
||||
ERROR_DEFINE( 95, CryptoError, false, RuntimeError);
|
||||
ERROR_DEFINE( 96, ParamInvalidError, false, RuntimeError);
|
||||
ERROR_DEFINE( 97, PathCloseError, false, RuntimeError);
|
||||
ERROR_DEFINE( 98, FileInfoError, false, RuntimeError);
|
||||
ERROR_DEFINE( 99, JsonFormatError, false, RuntimeError);
|
||||
ERROR_DEFINE(100, KernelError, false, RuntimeError);
|
||||
ERROR_DEFINE(101, ServiceError, false, RuntimeError);
|
||||
ERROR_DEFINE(102, ExecuteError, false, RuntimeError);
|
||||
ERROR_DEFINE(103, RepoInvalidError, false, RuntimeError);
|
||||
ERROR_DEFINE(104, CommandError, false, RuntimeError);
|
||||
ERROR_DEFINE(105, AccessError, false, RuntimeError);
|
||||
ERROR_DEFINE(122, RuntimeError, false, RuntimeError);
|
||||
ERROR_DEFINE(123, InvalidError, false, RuntimeError);
|
||||
ERROR_DEFINE(124, UnhandledError, false, RuntimeError);
|
||||
ERROR_DEFINE(125, UnknownError, false, RuntimeError);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Error type array
|
||||
|
||||
+20
-5
@@ -18,17 +18,18 @@ Represents an error type
|
||||
struct ErrorType
|
||||
{
|
||||
const int code;
|
||||
const bool fatal;
|
||||
const char *name;
|
||||
const struct ErrorType *parentType;
|
||||
};
|
||||
|
||||
// Macro for defining new error types
|
||||
#define ERROR_DEFINE(code, name, parentType) \
|
||||
const ErrorType name = {code, #name, &parentType}
|
||||
#define ERROR_DEFINE(code, name, fatal, parentType) \
|
||||
const ErrorType name = {code, fatal, #name, &parentType}
|
||||
|
||||
// Define test error
|
||||
#ifdef DEBUG
|
||||
ERROR_DEFINE(1, TestError, RuntimeError);
|
||||
ERROR_DEFINE(1, TestError, false, RuntimeError);
|
||||
#endif
|
||||
|
||||
// Include error type definitions
|
||||
@@ -112,6 +113,13 @@ errorTypeCode(const ErrorType *errorType)
|
||||
return errorType->code;
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
bool
|
||||
errorTypeFatal(const ErrorType *const errorType)
|
||||
{
|
||||
return errorType->fatal;
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
const ErrorType *
|
||||
errorTypeFromCode(int code)
|
||||
@@ -191,6 +199,13 @@ errorCode(void)
|
||||
return errorTypeCode(errorType());
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
bool
|
||||
errorFatal(void)
|
||||
{
|
||||
return errorTypeFatal(errorType());
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
const char *
|
||||
errorFileName(void)
|
||||
@@ -284,7 +299,7 @@ errorInternalJump(void)
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
bool
|
||||
errorInternalCatch(const ErrorType *const errorTypeCatch)
|
||||
errorInternalCatch(const ErrorType *const errorTypeCatch, const bool fatalCatch)
|
||||
{
|
||||
// If just entering error state clean up the stack
|
||||
if (errorInternalState() == errorStateTry)
|
||||
@@ -295,7 +310,7 @@ errorInternalCatch(const ErrorType *const errorTypeCatch)
|
||||
errorContext.tryList[errorContext.tryTotal].state++;
|
||||
}
|
||||
|
||||
if (errorInternalState() == errorStateCatch && errorInstanceOf(errorTypeCatch))
|
||||
if (errorInternalState() == errorStateCatch && errorInstanceOf(errorTypeCatch) && (fatalCatch || !errorFatal()))
|
||||
{
|
||||
errorContext.tryList[errorContext.tryTotal].uncaught = false;
|
||||
errorContext.tryList[errorContext.tryTotal].state++;
|
||||
|
||||
+18
-4
@@ -67,6 +67,9 @@ Functions to get information about a generic error type
|
||||
// Error type code
|
||||
int errorTypeCode(const ErrorType *errorType);
|
||||
|
||||
// Is the error type fatal
|
||||
bool errorTypeFatal(const ErrorType *errorType);
|
||||
|
||||
// Get error type using a code
|
||||
const ErrorType *errorTypeFromCode(int code);
|
||||
|
||||
@@ -88,6 +91,9 @@ const ErrorType *errorType(void);
|
||||
// Error code (pulled from error type)
|
||||
int errorCode(void);
|
||||
|
||||
// Is the error fatal?
|
||||
bool errorFatal(void);
|
||||
|
||||
// Error filename
|
||||
const char *errorFileName(void);
|
||||
|
||||
@@ -136,15 +142,23 @@ Catch a specific error thrown in the try block
|
||||
***********************************************************************************************************************************/
|
||||
#define CATCH(errorTypeCatch) \
|
||||
} \
|
||||
else if (errorInternalCatch(&errorTypeCatch)) \
|
||||
else if (errorInternalCatch(&errorTypeCatch, true)) \
|
||||
{
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Catch any non-fatal error thrown in the try block
|
||||
***********************************************************************************************************************************/
|
||||
#define CATCH_ANY() \
|
||||
} \
|
||||
else if (errorInternalCatch(&RuntimeError, false)) \
|
||||
{
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Catch any error thrown in the try block
|
||||
***********************************************************************************************************************************/
|
||||
#define CATCH_ANY() \
|
||||
#define CATCH_FATAL() \
|
||||
} \
|
||||
else if (errorInternalCatch(&RuntimeError)) \
|
||||
else if (errorInternalCatch(&RuntimeError, true)) \
|
||||
{
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
@@ -291,7 +305,7 @@ void errorInternalTryBegin(const char *fileName, const char *functionName, int f
|
||||
jmp_buf *errorInternalJump(void);
|
||||
|
||||
// True when in catch state and the expected error matches
|
||||
bool errorInternalCatch(const ErrorType *errorTypeCatch);
|
||||
bool errorInternalCatch(const ErrorType *errorTypeCatch, bool fatalCatch);
|
||||
|
||||
// Propagate the error up so it can be caught
|
||||
void errorInternalPropagate(void) __attribute__((__noreturn__));
|
||||
|
||||
+1
-1
@@ -296,7 +296,7 @@ main(int argListSize, const char *argList[])
|
||||
}
|
||||
}
|
||||
}
|
||||
CATCH_ANY()
|
||||
CATCH_FATAL()
|
||||
{
|
||||
error = true;
|
||||
result = exitSafe(result, true, 0);
|
||||
|
||||
@@ -284,7 +284,7 @@ protocolServerProcess(
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
}
|
||||
CATCH_ANY()
|
||||
CATCH_FATAL()
|
||||
{
|
||||
// Report error to the client
|
||||
protocolServerError(this, errorCode(), STR(errorMessage()), STR(errorStackTrace()));
|
||||
|
||||
@@ -84,7 +84,7 @@ Test that an expected error is actually thrown and error when it isn't
|
||||
{ \
|
||||
statement; \
|
||||
} \
|
||||
CATCH_ANY() \
|
||||
CATCH_FATAL() \
|
||||
{ \
|
||||
TEST_ERROR_catch = true; \
|
||||
\
|
||||
|
||||
@@ -32,12 +32,21 @@ testRun(void)
|
||||
|
||||
TEST_ERROR(bldErrParse(storageTest), FormatError, "error 'assert' code must be >= 25 and <= 125");
|
||||
|
||||
HRN_STORAGE_PUT_Z(
|
||||
storageTest, "src/build/error/error.yaml",
|
||||
"assert:\n"
|
||||
" bogus: 25");
|
||||
|
||||
TEST_ERROR(bldErrParse(storageTest), FormatError, "unknown error definition 'bogus'");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("parse and render error");
|
||||
|
||||
HRN_STORAGE_PUT_Z(
|
||||
storageTest, "src/build/error/error.yaml",
|
||||
"assert: 25\n"
|
||||
"assert:\n"
|
||||
" code: 25\n"
|
||||
" fatal: true\n"
|
||||
"option-invalid: 31\n"
|
||||
"runtime: 122\n");
|
||||
|
||||
@@ -81,9 +90,9 @@ testRun(void)
|
||||
COMMENT_BLOCK_BEGIN "\n"
|
||||
"Error type definitions\n"
|
||||
COMMENT_BLOCK_END "\n"
|
||||
"ERROR_DEFINE( 25, AssertError, RuntimeError);\n"
|
||||
"ERROR_DEFINE( 31, OptionInvalidError, RuntimeError);\n"
|
||||
"ERROR_DEFINE(122, RuntimeError, RuntimeError);\n"
|
||||
"ERROR_DEFINE( 25, AssertError, true, RuntimeError);\n"
|
||||
"ERROR_DEFINE( 31, OptionInvalidError, false, RuntimeError);\n"
|
||||
"ERROR_DEFINE(122, RuntimeError, false, RuntimeError);\n"
|
||||
"\n"
|
||||
COMMENT_BLOCK_BEGIN "\n"
|
||||
"Error type array\n"
|
||||
|
||||
@@ -12,9 +12,9 @@ ERROR_DECLARE(TestParent1Error);
|
||||
ERROR_DECLARE(TestParent2Error);
|
||||
ERROR_DECLARE(TestChildError);
|
||||
|
||||
ERROR_DEFINE(101, TestParent1Error, TestParent1Error);
|
||||
ERROR_DEFINE(102, TestParent2Error, TestParent1Error);
|
||||
ERROR_DEFINE(200, TestChildError, TestParent2Error);
|
||||
ERROR_DEFINE(101, TestParent1Error, false, TestParent1Error);
|
||||
ERROR_DEFINE(102, TestParent2Error, false, TestParent1Error);
|
||||
ERROR_DEFINE(200, TestChildError, false, TestParent2Error);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
testTryRecurse - test to blow up try stack
|
||||
@@ -164,6 +164,11 @@ testRun(void)
|
||||
|
||||
THROW(AssertError, bigMessage);
|
||||
}
|
||||
CATCH_ANY()
|
||||
{
|
||||
// Catch should not be executed since this error is fatal
|
||||
assert(false);
|
||||
}
|
||||
TRY_END();
|
||||
}
|
||||
CATCH(AssertError)
|
||||
@@ -179,7 +184,7 @@ testRun(void)
|
||||
}
|
||||
TRY_END();
|
||||
}
|
||||
CATCH_ANY()
|
||||
CATCH_FATAL()
|
||||
{
|
||||
assert(testErrorHandlerTryDepth == 2);
|
||||
|
||||
@@ -268,7 +273,7 @@ testRun(void)
|
||||
{
|
||||
THROW_CODE(25, "message");
|
||||
}
|
||||
CATCH_ANY()
|
||||
CATCH_FATAL()
|
||||
{
|
||||
assert(errorCode() == 25);
|
||||
assert(strcmp(errorMessage(), "message") == 0);
|
||||
@@ -311,7 +316,7 @@ testRun(void)
|
||||
errno = E2BIG;
|
||||
THROW_ON_SYS_ERROR(true, AssertError, "message");
|
||||
}
|
||||
CATCH_ANY()
|
||||
CATCH_FATAL()
|
||||
{
|
||||
printf("%s\n", errorMessage());
|
||||
assert(errorCode() == AssertError.code);
|
||||
@@ -325,7 +330,7 @@ testRun(void)
|
||||
errno = 0;
|
||||
THROW_ON_SYS_ERROR_FMT(true, AssertError, "message %d", 77);
|
||||
}
|
||||
CATCH_ANY()
|
||||
CATCH_FATAL()
|
||||
{
|
||||
printf("%s\n", errorMessage());
|
||||
assert(errorCode() == AssertError.code);
|
||||
@@ -339,7 +344,7 @@ testRun(void)
|
||||
errno = E2BIG;
|
||||
THROW_ON_SYS_ERROR_FMT(true, AssertError, "message %d", 77);
|
||||
}
|
||||
CATCH_ANY()
|
||||
CATCH_FATAL()
|
||||
{
|
||||
printf("%s\n", errorMessage());
|
||||
assert(errorCode() == AssertError.code);
|
||||
@@ -353,7 +358,7 @@ testRun(void)
|
||||
errno = 0;
|
||||
THROW_SYS_ERROR(AssertError, "message");
|
||||
}
|
||||
CATCH_ANY()
|
||||
CATCH_FATAL()
|
||||
{
|
||||
printf("%s\n", errorMessage());
|
||||
assert(errorCode() == AssertError.code);
|
||||
@@ -367,7 +372,7 @@ testRun(void)
|
||||
errno = EIO;
|
||||
THROW_SYS_ERROR_FMT(AssertError, "message %d", 1);
|
||||
}
|
||||
CATCH_ANY()
|
||||
CATCH_FATAL()
|
||||
{
|
||||
printf("%s\n", errorMessage());
|
||||
assert(errorCode() == AssertError.code);
|
||||
@@ -381,7 +386,7 @@ testRun(void)
|
||||
errno = 0;
|
||||
THROW_SYS_ERROR_FMT(AssertError, "message %d", 1);
|
||||
}
|
||||
CATCH_ANY()
|
||||
CATCH_FATAL()
|
||||
{
|
||||
printf("%s\n", errorMessage());
|
||||
assert(errorCode() == AssertError.code);
|
||||
|
||||
@@ -69,7 +69,7 @@ testRun(void)
|
||||
{
|
||||
THROW(RuntimeError, "test error message");
|
||||
}
|
||||
CATCH_ANY()
|
||||
CATCH_FATAL()
|
||||
{
|
||||
exitSafe(0, true, signalTypeNone);
|
||||
TEST_RESULT_LOG(
|
||||
@@ -90,7 +90,7 @@ testRun(void)
|
||||
{
|
||||
hrnErrorThrowP(.errorType = &RuntimeError, .message = "test debug error message");
|
||||
}
|
||||
CATCH_ANY()
|
||||
CATCH_FATAL()
|
||||
{
|
||||
exitSafe(0, true, signalTypeNone);
|
||||
TEST_RESULT_LOG(
|
||||
@@ -120,7 +120,7 @@ testRun(void)
|
||||
{
|
||||
hrnErrorThrowP(.message = "test assert message");
|
||||
}
|
||||
CATCH_ANY()
|
||||
CATCH_FATAL()
|
||||
{
|
||||
exitSafe(0, true, signalTypeNone);
|
||||
TEST_RESULT_LOG(
|
||||
|
||||
@@ -521,6 +521,14 @@ testRun(void)
|
||||
protocolServerProcess(server, NULL, commandHandler, PROTOCOL_SERVER_HANDLER_LIST_SIZE(commandHandler)),
|
||||
ProtocolError, "invalid command 'BOGUS' (0x38eacd271)");
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("server restart and assert");
|
||||
|
||||
// This does not run in a TEST* macro because tests are run by the command handlers
|
||||
TEST_ERROR(
|
||||
protocolServerProcess(server, NULL, commandHandler, PROTOCOL_SERVER_HANDLER_LIST_SIZE(commandHandler)),
|
||||
AssertError, "ERR_MESSAGE");
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("server restart");
|
||||
|
||||
@@ -608,7 +616,7 @@ testRun(void)
|
||||
protocolClientExecute(client, protocolCommandNew(TEST_PROTOCOL_COMMAND_ASSERT), false);
|
||||
THROW(TestError, "error was expected");
|
||||
}
|
||||
CATCH_ANY()
|
||||
CATCH_FATAL()
|
||||
{
|
||||
TEST_RESULT_PTR(errorType(), &AssertError, "check type");
|
||||
TEST_RESULT_Z(errorFileName(), TEST_PGB_PATH "/src/protocol/client.c", "check file");
|
||||
|
||||
+1
-1
@@ -236,7 +236,7 @@ main(int argListSize, const char *argList[])
|
||||
fflush(stdout);
|
||||
#ifdef HRN_FEATURE_ERROR
|
||||
}
|
||||
CATCH_ANY()
|
||||
CATCH_FATAL()
|
||||
{
|
||||
// Make the error really obvious
|
||||
fprintf(
|
||||
|
||||
Reference in New Issue
Block a user