Hi @tdapper  thanks for reaching out us.
With regard to your comment, although I confirm that you don't have to put them in a separate framework but it's actually recommended to grant good design and straightforward reusability.
For the sake of clarity, find below the files used to create a project which includes both the declaration and the implementation of the custom error together with the code using it. The example is derived from the code presented on GitHub.
project/projectdefinition.txt
// Supported platforms - can be [Win64;OSX]
Platform=Win64;OSX
// Type of project - can be [Lib;DLL;App]
Type=DLL
// API dependencies
APIS=cinema.framework;mesh_misc.framework;math.framework;crypt.framework;python.framework;core.framework;
// C4D component
C4D=true
stylecheck.level=3 // must be set after c4d=true
stylecheck.enum-registration=false
stylecheck.enum-class=false
ModuleId=net.maxonexample.support.single_plugins.PC12316
source/PC12316_CustomErrorImpl.cpp
#include "PC12316_CustomErrorInterface.h"
// This example shows the implementation of a custom error type.
class PC12316_CustomErrorImpl : public maxon::Component<PC12316_CustomErrorImpl, PC12316_CustomErrorInterface>
{
	// use ErrorObjectClass to implement basic error functionality
	MAXON_COMPONENT(NORMAL, maxon::ErrorObjectClass);
	
public:
	maxon::Result<void> CopyFrom(const PC12316_CustomErrorImpl& src)
	{
		_errorCode = src._errorCode;
		return maxon::OK;
	}
	
public:
	
	MAXON_METHOD maxon::String GetMessage() const
	{
		return FormatString("Custom error code is @", _errorCode);
	}
	
	// custom methods
	
	MAXON_METHOD void SetCustomErrorCode(maxon::Int errorCode)
	{
		_errorCode = errorCode;
	}
	
	MAXON_METHOD maxon::Int GetCustomErrorCode() const
	{
		return _errorCode;
	}
	
private:
	maxon::Int _errorCode;		///< error code value
};
// register all the non-static methods in the implementation
MAXON_COMPONENT_OBJECT_REGISTER(PC12316_CustomErrorImpl, PC12316_CustomErrorObject);
source/PC12316_CustomErrorInterface.h
#ifndef PC12316_CUSTOMERRORINTERFACE_H__
#define PC12316_CUSTOMERRORINTERFACE_H__
#include "maxon/object.h"
// This example shows the declaration of a custom error type.
// The custom error is able to store a custom error code.
// ---------------------------------------------------------------------
// Custom error class that stores an error code.
// ---------------------------------------------------------------------
class PC12316_CustomErrorInterface : MAXON_INTERFACE_BASES(maxon::ErrorInterface)
{
	MAXON_INTERFACE(PC12316_CustomErrorInterface, MAXON_REFERENCE_COPY_ON_WRITE, "net.maxonexample.example.errors.PC12316_customerror");
	
public:
	MAXON_ADD_TO_COPY_ON_WRITE_REFERENCE_CLASS(
											   void Create(MAXON_SOURCE_LOCATION_DECLARATION, maxon::Int errorCode)
											   {
#if API_VERSION >= 20000 && API_VERSION < 21000
												   * static_cast<typename S::DirectlyReferencedType::ReferenceClassHelper::type*>(this) = S::DirectlyReferencedType::ReferenceClassHelper::object::GetInstance() ();
#elif API_VERSION >= 21000
												   *static_cast<typename S::DirectlyReferencedType::Hxx1::ReferenceClass*>(this) = S::DirectlyReferencedType::Hxx1::ErrObj::GetInstance()();
#endif
												   typename S::DirectlyReferencedType::Ptr e = this->MakeWritable(false).GetPointer();
												   e.SetLocation(MAXON_SOURCE_LOCATION_FORWARD);
												   e.SetCustomErrorCode(errorCode);
											   }
											   );
	
	// custom methods
	
	// ---------------------------------------------------------------------
	// Stores an custom error code.
	// ---------------------------------------------------------------------
	MAXON_METHOD void	SetCustomErrorCode(maxon::Int errorCode);
	
	// ---------------------------------------------------------------------
	// Returns the stored custom error code.
	// ---------------------------------------------------------------------
	MAXON_METHOD maxon::Int GetCustomErrorCode() const;
};
#include "PC12316_CustomErrorInterface1.hxx"
#include "PC12316_CustomErrorInterface2.hxx"
#endif /* PC12316_CUSTOMERRORINTERFACE_H__ */
source/PC12316.cpp
#include "c4d.h"
static const Int32 PluginID = 99912316;
#include "PC12316_CustomErrorInterface.h"
// Dummy test function
maxon::Result<void> TestFunction(maxon::Int * val);
maxon::Result<void> TestFunction(maxon::Int * val)
{
	iferr_scope;
	
	if (!val)
		return PC12316_CustomError(MAXON_SOURCE_LOCATION, 4242);
	
	ApplicationOutput("Value is @", *val);
	
	return maxon::OK;
}
// Command to test the custom error
class CustomErrorExample : public CommandData
{
public:
	
#if API_VERSION >= 20000 && API_VERSION < 21000
	Bool Execute(BaseDocument* doc)
#elif API_VERSION >= 21000
	Bool Execute(BaseDocument* doc, GeDialog* parentManager)
#endif
	{
		iferr_scope_handler
		{
			return false;
		};
		
		if (!doc)
			return false;
		
		iferr (TestFunction(nullptr))
			ApplicationOutput("Error: @", err);
		
		maxon::Int a = 100;
		
		iferr (TestFunction(&a))
			ApplicationOutput("Error: @", err);
				
		return true;
	}
	
	static CommandData* Alloc() { return NewObj(CustomErrorExample) iferr_ignore("Unexpected failure on allocating CustomErrorExample plugin."_s); }
};
Bool RegisterCustomErrorExample();
Bool RegisterCustomErrorExample()
{
	return RegisterCommandPlugin(PluginID, "PC12316_CustomErrorExample"_s, PLUGINFLAG_COMMAND_OPTION_DIALOG, nullptr, ""_s, CustomErrorExample::Alloc());
}
Bool PluginStart()
{
	if (!RegisterCustomErrorExample())
		return false;
	return true;
}
void PluginEnd()
{
}
Bool PluginMessage(Int32 id, void* data)
{
	return true;
}
A final minor note on register=true: since R21 it's not needed anymore because in former releases it was needed to specify when a module was supposed to run in pure legacy-mode but nowadays modules can be either hybrid (classic + maxon API) or maxon API-only.
Hoping this makes using our Error Handling system more clear and easy to integrate in your products, give best and don't hesitate to ask for more.
Best, R