PrevUpHomeNext

Error reporting and handling

Error code enumeration
Basic exception class
Missing function errors
Limit errors
Object errors
Program variable errors
Program build errors
Framebuffer errors
Deferred error handlers
Function outcome

In order to detect and report any errors that occured during the calls to OpenGL functions, OGLplus consistently checks the result of the glGetError function and if an error is indicated it throws an instance of an appropriate exception class. The exceptions (described below) contain a lot of useful information about the error and are highly configurable. In debug builds all available information about the errors can be included, on the other hand when high performance is required most of the data members can be compiled-away by setting the appropriate compile-time configuration options making the exceptions more lightweight.

#include <oglplus/error/code.hpp>

ErrorCode enumerates the GL error code values. The GL error code can be obtained for example by calling the Code member function of Error.

enum class ErrorCode : GLenum
{
	NoError                     = GL_NO_ERROR,
	OutOfMemory                 = GL_OUT_OF_MEMORY,
	InvalidEnum                 = GL_INVALID_ENUM,
	InvalidValue                = GL_INVALID_VALUE,
	InvalidOperation            = GL_INVALID_OPERATION,
	InvalidFramebufferOperation = GL_INVALID_FRAMEBUFFER_OPERATION,
	StackOverflow               = GL_STACK_OVERFLOW,
	StackUnderflow              = GL_STACK_UNDERFLOW,
	TableTooLarge               = GL_TABLE_TOO_LARGE,
	ContextLost                 = GL_CONTEXT_LOST
};

template <>
Range<ErrorCode> EnumValueRange<ErrorCode>(void);

StrCRef EnumValueName(ErrorCode);

#include <oglplus/error/basic.hpp>

Error is an exception class for general OpenGL errors. Instances of this exception class are thrown whenever an error is detected during the execution of OpenGL API calls in the OGLplus code. This class is derived from the standard runtime_error exception and thus the basic error message can be obtained by calling its what() member function. There are several other classes derived for more specific error types, like GL shading language compilation and linking errors, limit errors, etc.

class Error
 : public std::runtime_error
{
public:
	static const char* Message(GLenum error_code); 1

	Error(const char* message); 2
	~Error(void) throw() { }

	ErrorCode Code(void) const; 3

	const char* SourceFile(void) const; 4
	const char* SourceFunc(void) const; 5
	unsigned SourceLine(void) const; 6

	const char* GLLib(void) const; 7
	const char* GLFunc(void) const; 8

	GLenum EnumParam(void) const; 9
	const char* EnumParamName(void) const; 10

	GLint Index(void) const; 11

1

Returns a message for the specified error_code.

2

Constructs a new instance of Error with the specified error message.

3

Return the GL error code associated with this error.

4

Returns the name of the OGLplus source file where the error occured. The result of this function is also influenced by the OGLPLUS_ERROR_NO_FILE preprocessor configuration option. If set to zero, this function behaves as described above, otherwise it returns a nullptr.

5

Returns the name of the OGLplus function where the error occured. The result of this function is also influenced by the OGLPLUS_ERROR_NO_FUNC preprocessor configuration option. If set to zero, this function behaves as described above, otherwise it returns a nullptr.

6

Returns the line of the OGLplus source file where the error occured. The result of this function is also influenced by the OGLPLUS_ERROR_NO_LINE preprocessor configuration option. If set to zero, this function behaves as described above, otherwise it returns zero.

7

This function returns the name of the GL library ("gl", "wgl", "glX") where the error occured. The result of this function is also influenced by the OGLPLUS_ERROR_NO_GL_LIB preprocessor configuration option. If set to zero, this function behaves as described above, otherwise it returns nullptr.

8

This function returns the name of the failed OpenGL function (without the gl prefix) which is related to the error. The result of this function is also influenced by the OGLPLUS_ERROR_NO_GL_FUNC preprocessor configuration option. If set to zero, this function behaves as described above, otherwise it returns nullptr.

9

Returns the value of the enumeration parameter related to the error. If no enum parameter is available, this function returns zero. The result of this function is also influenced by the OGLPLUS_ERROR_NO_GL_SYMBOL preprocessor configuration option. If set to zero, this function behaves as described above, otherwise it returns zero.

10

Returns the name of the enumeration parameter related to the error. If the enum parameter name is not available, this function returns zero. The result of this function is also influenced by the OGLPLUS_ERROR_NO_GL_SYMBOL preprocessor configuration option. If set to zero, this function behaves as described above, otherwise it returns nullptr.

11

Returns the value of an index parameter passed to the failed OpenGL function if applicable. If no index value is available then this function return a negative integer. The result of this function is also influenced by the OGLPLUS_ERROR_NO_GL_SYMBOL preprocessor configuration option. If set to zero, this function behaves as described above, otherwise it returns a negative integer.

	virtual GLfloat Value(void) const; 1
	virtual GLfloat Limit(void) const; 2

	virtual GLenum BindTarget(void) const; 3
	virtual const char* TargetName(void) const; 4

	virtual GLenum ObjectType(void) const; 5
	virtual const char* ObjectTypeName(void) const; 6
	virtual GLint ObjectName(void) const; 7
	virtual const std::string& ObjectDesc(void) const; 8

	virtual GLenum SubjectType(void) const; 9
	virtual const char* SubjectTypeName(void) const; 10
	virtual GLint SubjectName(void) const; 11
	virtual const std::string& SubjectDesc(void) const; 12

	virtual const char* Identifier(void) const; 13

	virtual const String& Log(void) const; 14
};

1

Returns a value parameter related to the error, if applicable, returns zero otherwise.

2

Returns a limit value related to the error, if applicable, returns zero otherwise.

3

Returns the object bind target, if applicable, returns zero otherwise.

4

Returns the object bind target name, if applicable, return nullptr otherwise.

5

If the error is related to a GL object, then an object type enumeration value is returned. Otherwise the result is zero.

6

If the error is related to a GL object, then a C string storing object type name is returned. Otherwise the result is nullptr.

7

If the error is related to a GL object, then the numeric GL name of the object is returned. Otherwise the result is a negative integer.

8

If the error is related to a GL object, then a std::string storing object description is returned. Otherwise the result is an empty std::string.

9

If the error is related to a pair of GL objects, then an object type enumeration value is returned. Otherwise the result is zero.

10

If the error is related a pair of GL objects, then a C string storing secondary object type name is returned. Otherwise the result is nullptr.

11

If the error is related to a pair of GL objects, then the numeric GL name of the secondary object is returned. Otherwise the result is a negative integer.

12

If the error is related to a pair of GL objects, then a std::string storing the secondary object description is returned. Otherwise the result is an empty std::string.

13

If the error is related to a GPU program variable (vertex attrib, uniform, subroutine, etc.) then this function returns a C string storing the identifier of the variable. Otherwise the result is nullptr.

14

If the error was caused by a process (like shader compilation, program linking or validation, etc.) which creates a textual log and it is available then it is returned by this function. Otherwise the result is an empty String.

#include <oglplus/error/glfunc.hpp>

Exception class for situations when a pointer to a GL function is invalid. OGLplus optionally (based on the value of the OGLPLUS_NO_GLFUNC_CHECKS compile-time switch) checks, if pointers to OpenGL functions are valid (i.e. not nullptr). OpenGL functions are usually called through pointers, when using a library such as GLEW, which tries to find and get the addresses of GL functions from the GL library dynamically at run-time. Sometimes the pointers to several of the functions remain uninitialized and usually result in a memory violation and program termination if called. The MissingFunction exception class indicates that the usage of such uninitialized function pointer was detected at run-time and allows the application to avoid memory access violation and terminate more gracefully.

class MissingFunction
 : public Error
{
public:
	MissingFunction(const char* message);
};

#include <oglplus/error/limit.hpp>

Exception indicating that a GL implementation-defined limit has been exceeded. Instances of this class are thrown if an instance of a numeric type is assigned a value that it is outside of an implementation dependent range. This includes things like limits on the number of texture units of the GPU, maximum texture dimensions, maximum number of draw buffers, vertex attributes, etc.

class LimitError
 : public Error
{
public:
	LimitError(const char* message);

	GLfloat Value(void) const; 1
	GLfloat Limit(void) const; 2
};

1

Returns the value, which triggered the error.

2

Returns the limit value, which has been exceeded.

#include <oglplus/error/object.hpp>

Exception class indicating that an OGLplus object-related error has occured.

class ObjectError
 : public Error
{
public:
	ObjectError(const char* message);

	GLenum ObjectType(void) const; 1
	const char* ObjectTypeName(void) const; 2

	GLenum BindTarget(void) const; 3
	const char* TargetName(void) const; 4

	GLint ObjectName(void) const; 5
	const String& ObjectDesc(void) const; 6
};

1

Returns the OpenGL constant value determining the object type (like GL_PROGRAM, GL_TEXTURE, GL_SHADER, GL_BUFFER, etc.), which caused the error. If the object type is not available the value zero is returned.

2

Returns a c-string (without the GL_ prefix) corresponding to the GL constant determining the object type (like "PROGRAM", "TEXTURE", "SHADER", "BUFFER", "SAMPLER", etc.). If the object type name is not available then nullptr is returned.

3

Returns the OpenGL constant value determining the bind target, to which the object related to the error was bound. If the target is not available the value zero is returned.

4

Returns a c-string (without the GL_ prefix) corresponding to the GL constant determining the bind target. If the target name is not available then nullptr is returned.

5

Returns the raw OpenGL (integer) name of the object, which caused the error. If the object name is not available then a negative integer value is returned.

6

Returns a textual description of the object, which caused the error. If no description is available, then an empty String is returned.

ObjectPairError indicates that an error related to a pair of OGLplus objects has occured. The two objects in the pair are referred-to as object and subject.

class ObjectPairError
 : public ObjectError
{
public:
	ObjectPairError(const char* message);

	GLenum SubjectType(void) const; 1
	const char* SubjectTypeName(void) const; 2

	GLint SubjectName(void) const; 3
	const String& SubjectDesc(void) const; 4
};

1

Returns the OpenGL constant value determining the type of the subject, in the object pair which caused the error. If the subject type is not available the value zero is returned.

2

Returns a c-string (without the GL_ prefix) corresponding to the GL constant determining the subject type. If the subject type name is not available then nullptr is returned.

3

Returns the OpenGL (integer) name of the subject in the object pair, which caused the error. If the object name is not available then a negative integer value is returned.

4

Returns a textual description of the subject, which caused the error. If no description is available, then an empty String is returned.

#include <oglplus/error/prog_var.hpp>

Exception class indicating that an error related to a program variable (like an Uniform, VertexAttrib, etc.) has occured.

class ProgVarError
 : public Error
{
public:
	ProgVarError(const char* message);

	const char* ObjectTypeName(void); 1
	GLint ObjectName(void) const; 2
	ProgramName Program(void) const; 3

	const char* Identifier(void) const; 4
};

1

Returns the string "PROGRAM".

2

Returns the raw GL name of the program related to this error.

3

Returns the name of the program related to this error.

4

Returns a c-string containing the identifier of the GPU program variable related to this error.

#include <oglplus/error/program.hpp>

Generic base exception for program build errors.

class ProgramBuildError
 : public ObjectError
{
public:
	ProgramBuildError(const char* message);

	const String& Log(void) const; 1
};

1

Returns the output of the GLSL shader compiler, program linker or validator. If no output is available then an empty String is returned.

Exception for Shader compilation errors.

class CompileError
 : public ProgramBuildError
{
public:
	CompileError(const char* message);
};

Exception for Program linking errors.

class LinkError
 : public ProgramBuildError
{
public:
	LinkError(const char* message);
};

Exception for Program validation errors.

class ValidationError
 : public ProgramBuildError
{
public:
	ValidationError(const char* message);
};

#include <oglplus/error/framebuffer.hpp>

Exception indicating that an incomplete GL framebuffer error has occured.

class IncompleteFramebuffer
 : public ObjectError
{
public:
	IncompleteFramebuffer(const char* message);

	FramebufferStatus Status(void) const; 1
};

1

Returns the status of the Framebuffer that raised this error.

#include <oglplus/error/deferred_handler.hpp>

Most OGLplus functions throw exceptions (or generally call the HandleError function) eagerly within their body immediately after an error is detected. In some cases it is however desirable to allow to postpone or cancel the error handling. Such function return (usually indirectly) a class which is derived from or contains an instance of DeferredHandler which wraps the error handler function and unless it is cancelled it invokes it at the latest in the destructor.

There are very few reasons to use DeferredHandler directly in library user code. Use the derived or related classes like Outcome instead.

class DeferredHandler
{
public:
	DeferredHandler(DeferredHandler&&);

	~DeferredHandler(void); 1

	void trigger(void); 2
	bool cancel(void) 3
	noexcept;

	explicit
	operator bool (void) const 4
	noexcept;

	bool operator ! (void) const 5
	noexcept;
};

1

Invokes the error handler (which usually throws an exception) unless the handler already has been triggered or it was cancelled.

2

If this instance wraps an error handler, it is invoked

3

If this instance wraps an error handler, this function cancels its invocation and returns true, otherwise returns false.

4

Returns true if this instance wraps an error handler.

5

Returns true if this instance does not wrap an error handler.

#include <oglplus/error/outcome.hpp>

Most OGLplus functions throw exceptions (or generally call the HandleError function) eagerly within their body immediately after an error is detected. In some cases it is however desirable to allow to postpone or cancel the error handling. Such function return an instance of the Outcome<T> class template.

template <typename T>
class Outcome
{
private:
	DeferredHandler handler; 1
public:
	Outcome(Outcome&&);

	T Then(void); 2

	bool Done(void) const; 3

	bool DoneWithoutError(void); 4
};

1

The error handler is invoked in the destructor unless it is dismissed.

2

If the operation which produced this instance of Outcome generated an error, then its handler is invoked, otherwise this function returns the resulting value of that operation.

3

Returns true if the operation which produced this instance completed without error, returns false otherwise. The error handler is not dismissed and will be invoked later.

4

If the operation that produced this instance ended with an error then the error handler is dismissed (cancelled) and will not be invoked and false is returned, otherwise this function returns true.

Example of usage

The following snippet shows the usage of Outcome returned by Shader::Compile(std::noexcept_t). The logical operator short circuiting together with the DoneWithoutError and Done member function allows to find the first shader source which can be compiled in the current GL context. Note that the last line uses the Done function which throws in case that even the last shader source fails to compile.

VertexShader shader;

const char* source_glsl_430 = /* ... */;
const char* source_glsl_330 = /* ... */;
const char* source_glsl_150 = /* ... */;
const char* fallback_source = /* ... */;

shader.Source(source_glsl_430).Compile(std::nothrow).DoneWithoutError() ||
shader.Source(source_glsl_330).Compile(std::nothrow).DoneWithoutError() ||
shader.Source(source_glsl_150).Compile(std::nothrow).DoneWithoutError() ||
/* ... */
shader.Source(fallback_source).Compile(std::nothrow).Done();
Positive outcome

PositiveOutcome adds two boolean operators to Outcome: explicit conversion to bool which returns true if the instance of Outcome does not hold an error handler (i.e. if the function call which returned it finished successfully) or false otherwise, and operator ! which does the opposite.

template <typename T>
class PositiveOutcome
 : public Outcome<T>
{
public:
	explicit
	operator bool (void) const 1
	noexcept;

	bool operator ! (void) const 2
	noexcept;
};

template <typename T>
PositiveOutcome<T> Succeeded(Outcome<T>&& outcome) 3
noexcept;

1

Returns true if the operation that produced this instance completed without an error, returns false otherwise.

2

Returns false if the operation that produced this instance completed without an error, returns true otherwise.

3

Converts Outcome to PositiveOutcome.

The following code shows the usage of PositiveOutcome and the Succeeded function.

VertexShader shader;

if(auto compiled_shader = Succeeded(shader.Source(source).Compile(std::nothrow)))
{
	/* Shader compiled successfully */
}
else
{
	/* Shader compilation failed */
}
Negative outcome

Similar to PositiveOutcome, NegativeOutcome also adds two boolean operators to Outcome, however the logic is inverted. Explicit conversion to bool returns true in case of an error and false otherwise.

template <typename T>
class NegativeOutcome
 : public Outcome<T>
{
public:
	explicit
	operator bool (void) const 1
	noexcept;

	bool operator ! (void) const 2
	noexcept;
};

template <typename T>
NegativeOutcome<T> Failed(Outcome<T>&& outcome) 3
noexcept;

1

Returns false if the operation that produced this instance completed without an error, returns true otherwise.

2

Returns true if the operation that produced this instance completed without an error, returns false otherwise.

3

Converts Outcome to NegativeOutcome.

The following code shows the usage of NegativeOutcome and the Failed function.

VertexShader shader;

if(auto compilation_failed = Failed(shader.Source(source).Compile(std::nothrow)))
{
	/* Shader compilation failed */
}
else
{
	/* Shader compiled successfully */
}

PrevUpHomeNext