This question already has answers here:
How to throw a C++ exception
(5 answers)
Closed 4 years ago.
How to throw a C++ exception
c++ exception-handling
I have a very poor understanding of exception handling(i.e., how to customize throw, try, catch statements for my own purposes).
For example, I have defined a function as follows: int compare(int a, int b){...}
I'd like the function to throw an exception with some message when either a or b is negative.
How should I approach this in the definition of the function?
Not at all.
The definition of the function stays
int compare(int a, int b);
whether or not you throw an exception (forget about throw(exception), it's considered bad practice and is deprecated).
If you want to throw an exception if either a or b is negative, you put this code in your methods implementation:
int compare(int a, int b)
{
if(a < 0 || b < 0)
{
throw std::logic_error("a and be must be positive");
}
// the comparing code here
}
and that's all it takes for the method to throw. Note that you need to #include <stdexcept>.
For the calling code (e.g. main) you would do it this way:
int result;
try
{
result = compare(42, -10);
}
catch(const std::logic_error& ex)
{
// Handle the exception here. You can access the exception and it's members by using the 'ex' object.
}
Note how we catch the exception as a const reference in the catch clause so that you can access the exceptions members such as ex.what() which gives you the exception message, in this case
"a and be must be positive"
Note.
You can of course throw other exception types (even your own, custom exceptions), but for this example I found std::logic_error the most appropriate, since it reports a faulty logic.
Related
I'm running a boost::thread which is interrupted from somewhere else in my program.
auto my_thread = boost::thread(&threadedFunction, this);
Is using a function-try-block like this
void threadedFunction() try {
// do stuff
} catch (boost::thread_interrupted &) {
// handle error
}
equivalent to using a try-catch block encompassing the entire function?
void threadedFunction() {
try {
// do stuff
} catch (boost::thread_interrupted &) {
// handle error
}
}
They may not be equivalent, since my_thread can be interrupted before the try block is entered, and in that case, the program would crash. That being said, I'm not sure if this is possible.
Are both chunks of code equivalent?
Yes, but not for constructor bodies.
That's why function-try-block was invented:
The primary purpose of function-try-blocks is to respond to an exception thrown from the member initializer list in a constructor by logging and rethrowing, modifying the exception object and rethrowing, throwing a different exception instead, or terminating the program.
Side note: thread interruption
Boost's thread interruption mechanism is cooperative, not asynchronous (like POSIX signals). That means that, no between { and try { there cannot be an interruption:
https://www.boost.org/doc/libs/1_54_0/doc/html/thread/thread_management.html#thread.thread_management.this_thread.interruption_point
Even if were fully asynchronous, then still it would not make any sense to reason about the "difference" because there would not be any happens-before relationship anyways, so both outcomes could occur in both situations anyways (it's timing dependent regardless).
In my experience, the error handling strategy in various EIP components have little or no consistency.
Case 1: handle:
return IntegrationFlows.from(inputChannel)
.enrichHeaders(spec -> spec.header(ERROR_CHANNEL, ARTIFACTORY_ERROR_CHANNEL, true))
.handle(WebFlux.outboundGateway(uri, webClient)
.expectedResponseType(ArtifactSearchResponse.class)
.httpMethod(GET)
.mappedRequestHeaders(ACCEPT))
.log(LoggingHandler.Level.INFO, CLASS_NAME, Message::getPayload)
.handle(transformer)
.channel(outputChannel)
.get();
In this case, if handle(transformer) throws an exception, the message is sent to the ARTIFACTORY_ERROR_CHANNEL as expected, but the exception is returned to the caller. Thus, a test has to use try-catch to not fail.
try {
inputChannel.send(new GenericMessage<>("start"));
} catch (Exception e) {
// nop-op
}
verify(mockMessageHandler, timeout.times(1)).handleMessage(any(ErrorMessage.class));
Case 2: transform:
Change handle(transformer) to transform(transformer) and the exception is never sent to the ARTIFACTORY_ERROR_CHANNEL channel.
Case 3: Gateway:
public IntegrationFlow fileStreamingFlow() {
return IntegrationFlows.from(inputChannel)
.gateway(f -> f.handle(String.class, (fileName, headers) -> {
throw new RuntimeException();
}), spec -> spec.requiresReply(false).errorChannel(S3_ERROR_CHANNEL))
.channel(outputChannel)
.get();
}
}
In this case, the calls blocks forever. See #2451.
Case 4: handle with routeByException:
return IntegrationFlows.from(s3Properties.getFileStreamingInputChannel())
.enrichHeaders(spec -> spec.header(ERROR_CHANNEL, S3_ERROR_CHANNEL, true))
.handle(String.class, (fileName, h) -> {
return new ErrorMessage(new RuntimeException(), h);
}, spec -> spec.requiresReply(false))
.channel(outputChannel)
.routeByException(r -> r.channelMapping(Exception.class, S3_ERROR_CHANNEL))
.get();
}
In order for the exception to be sent to S3_ERROR_CHANNEL, I need to convert the exception to an ErrorMessage, and also apply a routeByException although there is already a previously configured ERROR_CHANNEL.
What I expect: If user defines an error channel, send all exceptions there. If the error handler associated to that channel returns null, terminate the flow; if it returns something else, continue. If user doesn't define an error channel, send the exception to the framework default error channel. Do this regardless of the flow definition.
transformer - if your transformer returns Message<?>; it is responsible to propagate the errorChannel header.
When using a gateway, the error channel must be declared thereon rather than adding it later.
I don't understand what you are trying to do there.
In general, it's best to not manipulate framework headers in this way, but declare the channel on the proper elements (gateways, pollers etc).
I want to verify exception throwing in one of my running threads. This is piece of my test code:
then:
def e = thrown(RequestFormatException)
e.message == "Incorrect first line: INCORRECT LINE"
When I run this I get next messages:
Exception in thread "Thread-1" by.westside.staircase.core.exception.RequestFormatException: Incorrect first line: INCORRECT LINE
at by.westside.staircase.core.util.HttpUtil.parseHttpRequest(HttpUtil.kt:19)
at by.westside.staircase.core.server.ServerThread.run(ServerThread.kt:26)
at java.lang.Thread.run(Thread.java:745)
Expected exception of type 'by.westside.staircase.core.exception.RequestFormatException', but no exception was thrown
at org.spockframework.lang.SpecInternals.checkExceptionThrown(SpecInternals.java:79)
at org.spockframework.lang.SpecInternals.thrownImpl(SpecInternals.java:66)
at by.westside.staircase.core.server.SyncServerSpec.should throw exception in incorrect first line case(SyncServerSpec.groovy:26)
Spock, like JUnit, can only assert on exceptions thrown from the thread executing the test, not "any thread in the application". Your exceptions are not caught by spock, and can't be asserted.
You can play with Thread.uncaughtExceptionHandler but you should probably unit-test the runnable executed in your thread - or implement some error handling in your business logic, and test this part of the code.
I think another option is to actually catch the exception in your test case and assert on that. here is a snippet of my code (written in Groovy Spock):
def exceptionThrown = false
def exceptionMessage
def thread = new Thread( {_ ->
try{
//code you are testing
} catch(Exception e) { // change this to the exception you want to catch
exceptionThrown = true
exceptionMessage = e.getMessage()
}
})
then: "the right exception should be thrown"
exceptionThrown
exceptionMessage = "I am thrown" //this should be your error message
I ran into the same issue and took a simple, hokey route. In the spirit of "good software is testable software" I added a flag and asserted on that, labeling it: // only for testing. Which, of course, will be ignored down the road.
thrown(RequestFormatException)
this should be in your first line after then: as this is the constraint imposed by spock.
Whenever thrown or notThrown is called in it should be the first statement.
Note: thrown and notThrown both return true and hence there should be no comparison operator as well.
Hence, In your case , it should be like below:
then:
thrown(RequestFormatException)
I'm constantly (since years) wondering the most senseful way to implement the following (it's kind of paradoxic for me):
Imagine a function:
DoSomethingWith(value)
{
if (value == null) { // Robust: Check parameter(s) first
throw new ArgumentNullException(value);
}
// Some code ...
}
It's called like:
SomeFunction()
{
if (value == null) { // Fail early
InformUser();
return;
}
DoSomethingWith(value);
}
But, to catch the ArgumentNullException, should I do:
SomeFunction()
{
if (value == null) { // Fail early
InformUser();
return;
}
try { // If throwing an Exception, why not *not* check for it (even if you checked already)?
DoSomethingWith(value);
} catch (ArgumentNullException) {
InformUser();
return;
}
}
or just:
SomeFunction()
{
try { // No fail early anymore IMHO, because you could fail before calling DoSomethingWith(value)
DoSomethingWith(value);
} catch (ArgumentNullException) {
InformUser();
return;
}
}
?
This is a very general question and the right solution depends on the specific code and architecture.
Generally regarding error handling
The main focus should be to catch the exception on the level where you can handle it.
Handling the exceptions at the right place makes the code robust, so the exception doesn't make the application fail and the exception can be handled accordingly.
Failing early makes the application robust, because this helps avoiding inconsistent states.
This also means that there should be a more general try catch block at the root of the execution to catch any non fatal application error which couldn't be handled. Which often means that you as a programmer didn't think of this error source. Later you can extend your code to also handle this error. But the execution root shouldn't be the only place where you think of exception handling.
Your example
In your example regarding ArgumentNullException:
Yes, you should fail early. Whenever your method is invoked with an invalid null argument, you should throw this exception.
But you should never catch this exception, cause it should be possible to avoid it. See this post related to the topic: If catching null pointer exception is not a good practice, is catching exception a good one?
If you are working with user input or input from other systems, then you should validate the input. E.g. you can display validation error on the UI after null checking without throwing an exception. It is always a critical part of error handling how to show the issues to users, so define a proper strategy for your application. You should try to avoid throwing exceptions in the expected program execution flow. See this article: https://msdn.microsoft.com/en-us/library/ms173163.aspx
See general thoughts about exception handling below:
Handling exceptions in your method
If an exception is thrown in the DoSomethingWith method and you can handle it and continue the flow of execution without any issue, then of course you should do those.
This is a pseudo code example for retrying a database operation:
void DoSomethingAndRetry(value)
{
try
{
SaveToDatabase(value);
}
catch(DeadlockException ex)
{
//deadlock happened, we are retrying the SQL statement
SaveToDatabase(value);
}
}
Letting the exception bubble up
Let's assume your method is public. If an exception happens which implies that the method failed and you can't continue execution, then the exception should bubble up, so that the calling code can handle it accordingly. It depends one the use-case how the calling code would react on the exception.
Before letting the exception bubble up you may wrap it into another application specific exception as inner exception to add additional context information. You may also process the exception somehow, E.g log it , or leave the logging to the calling code, depending on your logging architecture.
public bool SaveSomething(value)
{
try
{
SaveToFile(value);
}
catch(FileNotFoundException ex)
{
//process exception if needed, E.g. log it
ProcessException(ex);
//you may want to wrap this exception into another one to add context info
throw WrapIntoNewExceptionWithSomeDetails(ex);
}
}
Documenting possible exceptions
In .NET it is also helpful to define which exceptions your method is throwing and reasons why it might throw it. So that the calling code can take this into consideration. See https://msdn.microsoft.com/en-us/library/w1htk11d.aspx
Example:
/// <exception cref="System.Exception">Thrown when something happens..</exception>
DoSomethingWith(value)
{
...
}
Ignoring exceptions
For methods where you are OK with a failing method and don't want to add a try catch block around it all the time, you could create a method with similar signature:
public bool TryDoSomethingWith(value)
{
try
{
DoSomethingWith(value);
return true;
}
catch(Exception ex)
{
//process exception if needed, e.g. log it
ProcessException(ex);
return false;
}
}
I have a queue with a semaphore. At certain point all the calls to sem_post() always return 'Invalid argument' error although the semaphore itself is valid
The semaphore is a private member of C++ object which is never deleted, it also can be inspected in gdb. I added sem_getvalue() just before the sem_post() - the value reads OK and then it fails on sem_post(). What could be wrong?
CThreadQueue::CThreadQueue(int MaxSize) :
_MaxSize(MaxSize)
{
sem_init(&_TaskCount, 0, 0)
pthread_mutex_init(&_Mutex, 0);
pthread_create(&_Thread, NULL, CThreadQueue::StartThread, this);
}
CThreadQueue::~CThreadQueue()
{
pthread_kill(_Thread, SIGKILL);
sem_destroy(&_TaskCount);
}
int CThreadQueue::AddTask(CThreadTask Task)
{
pthread_mutex_lock(&_Mutex);
_Queue.push_back(TempTask);
sem_post(&_TaskCount)
pthread_mutex_unlock(&_Mutex);
return 0;
}
void *CThreadQueue::StartThread(void *Obj)
{
((CThreadQueue*)Obj)->RunThread();
return NULL;
}
//runs in a separate thread
void CThreadQueue::RunThread()
{
CThreadQueue::CTask Task;
while(1) {
sem_wait(&_TaskCount);
pthread_mutex_lock(&_Mutex);
Task = _Queue.front();
_Queue.pop_front();
pthread_mutex_unlock(&_Mutex);
if (Task.Callee != NULL)
Task.Callee->CallBackFunc(NULL, Task.CallParam);
}
}
What could be wrong? Any number of things. Something else could be destroying the semaphore or overwriting the memory used to store it or the pointer to it. Another possibility is that you're calling sem_post() too many times and the counter overflows. A code sample would help.
We had the same problem, and after a long time figuring out what could be happening, we discovered that the problem occurred because the semaphore was defined inside a struct that had its byte alignment changed to 1 (in this case using the pragma pack(1) directive).
The POSIX semaphores implementation on Linux uses the futex syscall. According to the futex man page, EINVAL is returned when "An operation was not defined or error in page alignment."
In our case, either removing the pragma pack(1) directive or defining the semaphore as the first element of the struct, solved the problem.