Skip to content

Conversation

@arng40
Copy link
Contributor

@arng40 arng40 commented Nov 5, 2025

Remove code duplication found in GEOS_THROW, GEOS_ERROR, GEOS_WARNING and put into a static function in ErrorLogger.
Called while flushErrorMsg().
Move all Exceptions under GeosExceptions.hpp

… link between GEOS_THROW_CTX_IF and LVARRAY_THROW_IF_TEST( EXP, MSG, TYPE )
… in try/catch statements

Problem: Retrieves everything that was thrown, so not just the message.
…y spaces.

The previous condition checked whether an argument was present and whether the option was immediately followed by a value like -test"value", which excluded valid cases like -test "value" et -test     "value".
Comment on lines 115 to 116
/// The signal received and formatted
std::string m_signal;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That little guy seems to never be initialized (addSignalToMsg()?)
Maybe you can just remove it and read the Attribute::Signal entry

}
catch( std::exception const & e )
{ // native exceptions management
ErrorLogger::ErrorMsg & errMsg = ErrorLogger::global().currentErrorMsg();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it lacks a lot of information here: at this point, IIRC, GEOS_THOW() has never been called, so the same information must be provided to the error message.

Appart from that, this part is a lot better!

oss << PREFIX<< "LOCATION: " << errMsg.m_file;
if( errMsg.m_line > 0 )
{
oss << " l." << errMsg.m_line;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You changed the format here in a way that prevent us, developpers, to ctrl+click the file location for quick access.

The LOCATION macro is:

#define LOCATION __FILE__ ":" STRINGIZE( __LINE__ )

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, you put an if there but not in the YAML format.

Comment on lines +167 to +173
:
m_type( msgType ),
m_msg( msgContent ),
m_ranksInfo( {rank} ),
m_file( msgFile ),
m_line( msgLine ),
m_commit( false ) {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-> cpp

* @return Reference to the current instance for method chaining.
*/
ErrorMsg & addToMsg( std::exception const & e, bool toEnd = false );
ErrorMsg & addToMsg( std::exception const & e, bool const toEnd = false );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those const added to boolean values are implementation details, not interface matter, it should remain in the cpp.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same for MsgType and integer below

Comment on lines +257 to +258
bool isCommited() const
{ return m_commit; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

About this "commit" concept:

  1. Why is it needed? What problem does it aim to solve? Is the "commited" state really needed?
  2. ErrorMsg is a data structure with some helper methods for building it, I don't think it should have any state in it.
  3. I see your new ErrorMsgBuilder class, with a lot of copied method, with some of them having silenciously no effect. Could the methods be better distributed?

I propose ErrorMsg being a POD, with no state, and ErrorMsgBuilder having all the building methods.
Also, I would not bind ErrorMsgBuilder to an ErrorLogger instance but to the ErrorMsg instance. This way you don't need this two ways dependancies anymore, which does not exist for good reasons (duplicating flush() & violating encapsulation).

* potencially at various application layers
* Use flushErrorMsg() when the message is fully constructed and you want it to be output
* @return Reference to the current instance for method chaining.
* potencially at various application layers (Typically for exceptions)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Typically for exceptions"
Are there other use-cases?

Comment on lines +346 to +349
ErrorMsgBuilder beginLogger()
{
return ErrorMsgBuilder( *this );
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that you tried to remove the "current error message" read-write accessor for encapsulation & clarity purpose, but I'm not sure the solution is better than the original: beginLogger() can be called multiple time in an exception stack scenario. I think buildCurrentErrorMsg() would be better named.
We could name flushErrorMsg() to flushCurrentErrorMsg() to emphasis the fact that the subject is the same.

Comment on lines 204 to 210
rank: 0
message: >-
Table input error.
Empty Group: Base Test Class (file.xml, l.23)
Empty Group
contexts:
- priority: 2
inputFile: /path/to/file.xml
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main context information are lost (Base Test Class (file.xml, l.23)).


private:
///@copydoc ErrorLogger::m_errorContext
ErrorLogger & m_errorContext;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you keep it:

Suggested change
ErrorLogger & m_errorContext;
ErrorLogger & m_errorLogger;

If you change it:

Suggested change
ErrorLogger & m_errorContext;
ErrorMsg & m_errorMsg;

Comment on lines +86 to +89
ErrorContext( map< Attribute, std::string > attributes, integer priority ):
m_dataDisplayString( "" ),
m_attributes( attributes ),
m_priority( priority ) {};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

m_dataDisplayString is allowed as empty? Isn't that the source of your issue in the unit test?

Comment on lines +132 to +140
ErrorLogger::global().beginLogger()
.addSignalToMsg( signal )
.setType( ErrorLogger::MsgType::Error )
.addRank( ::geos::logger::internal::g_rank )
.addCallStackInfo( stackHistory )
.addContextInfo(
ErrorContext{ { { ErrorContext::Attribute::Signal, std::to_string( signal ) } }, 1 },
ErrorContext{ { { ErrorContext::Attribute::DetectionLoc, string( "signal handler" ) } }, 0 } )
.flush();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a unit test for signals would be a good thing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci: run CUDA builds Allows to triggers (costly) CUDA jobs ci: run integrated tests Allows to run the integrated tests in GEOS CI type: cleanup / refactor Non-functional change (NFC)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants