I am facing a problem to get rest of items from observable after thrown an exception. Assume I have 10 items to emit, on second item, I throw an exception and my Subscriber onError got called with the exception thrown, after that, the rest 8 items will be emitted. How can i continue emitting the rest of 8 items to my subscriber (onNext) in here? Thanks
Use onErrorResumeNext to tell your pipeline what to emit in case of Exception. Looks this Unit test example.
#Test
public void observableOnErrorResumeException() {
Integer[] numbers = {0, 1, 2, 3, 4, 5};
Observable.from(numbers)
.doOnNext(number -> {
if (number > 3) {
try {
throw new IllegalArgumentException();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
})
.onErrorResumeNext(t -> Observable.just(666))
.subscribe(System.out::println);
}
This code will print
0
1
2
3
666
You can see more examples here https://github.com/politrons/reactive
Is the source emitting 10 items emitting an error or some operator in between? If the source is emitting an error then the resumption must be built into the source as there isn't an explicit contract in RxJava to resume.
If there is an operator in between that is emitting an error then that error has to be suppressed by something like onErrorResumeNext(). Looking at code makes it easier to comment.
Related
I have three exceptions classes in my code, so when i want to use more arguments (more different objects to catch i get an compile error) so how i can catch more exceptions?
i tried to do this
try{
User * u = new FacebookUser(username,password,email,friends,likes,comments);
network += u;
}
catch(InvalidPassword ip,InvalidEmail ie,MaximumSizeLimit ms){
ip.message();
ie.message();
ms.message():
}
First exception is for checking if password have at least 1 uppercase,lowercase and number.
Second exception is for checking if email have at least 1 # .
Third exception is for changing static variable, if the maximum is equal to n throw exception.
My throw exceptions for email and password are in my user constructor.
If you have multiple types of exceptions you want to catch, you need to catch them separately - otherwise, what would be in say ip if InvalidEmail was thrown?
Correct code will be like
try {
//...
} catch (const InvalidPassword& ip) {
//...
} catch (const InvalidEmail& ie) {
//...
} catch (const MaximumSizeLimit& ms) {
//...
}
Othewrise, you can make all this exceptions inherited to the same base class and make message virtual function of this base class.
(as a separate note, it is sometimes considered bad style to use exceptions for such checks)
I a couple of C++ examples I've seen throw 1 in catch block. Tried to find out what it may be, but always found a classical example with exception object or rethrowing an exception without any argument.
Also sometimes I can find in Internet other examples, also without explanations:
throw 1
throw 2
throw -1
Tell me please what it may mean.
Tell me please what it may mean.
It means you're throwing a value of a int that has the value 1, 2 or -1.
Of course, without any further detail, it's hard to infer a meaning on this.
A use case would be to report error code from a function:
int returning_error_code() {
try {
stuff();
} catch (int e) {
return e; // return error code
}
return 0; // no error
}
throw 1
throw 2
throw -1
Tell me please what it may mean.
throw throws an object. throw 1 throws an object if type int with the value 1. I assume the reader can extrapolate what the other two mean.
This is an exception mechanism. The thrown object can be caught:
try {
throw 1;
} catch (int e) {
std::cout << "an integer was thrown and caught. here is the value: " << e;
}
I've seen throw 1 in catch block.
Throwing inside an exception handler is allowed. It has same behaviour as throwing outside a handler.
always found a classical example with exception object or rethrowing an exception without any argument.
This is a case of throwing an exception object.
There is no limitation to the type of objects that can be thrown. The standard library follows the convention of throwing only classes derived from std::exception. Following this convention in user programs is recommended.
I'm using the asio networking library. I'm seeing a very strange behaviour where the debugger tells me that the call to std::map::at() throws an out_of_range exception, however I have catch block to catch precisely that type of exception!
The map in question is this:
/*Both of these maps are global variables in the namespace cloud*/
map<string, weak_ptr<session> > cloud::services;
map<string, vector<weak_ptr<session> > > cloud::subscribed; //this one
And the code that's throwing the exception is this:
void session::subscribirse(std::string a_which)
{
try
{
//We obtain a reference to the group of sockets subscribed to this service name
vector<weak_ptr<session>>& grupo = cloud::subscribed.at(a_which); //HERE
grupo.emplace_back(shared_from_this() );
}
catch(out_of_range& e) //The group didn't exist (no-one had subscribed to it yet)
{
vector<weak_ptr<session>> new_group;
new_group.emplace_back(shared_from_this());
cloud::subscribed.emplace(make_pair(a_which, new_group));
}
catch(...)
{
cout << "unexpected exception during subscribe\n";
}
subscriptions_.emplace_back(a_which);
consumed_ = true;
}
Could the catch-block be rethrowing and the debugger not being capable of detecting that? (I really don't think so).
Sorry if question is not clear, I've spent the last 6 hours and I'm feeling desperate.
The [] operator will insert an empty value if it doesn't already exist and doesn't throw.
cloud::subscribed[a_which].emplace_back(shared_from_this() );
You can check for the existence of a key using find():
if(cloud::subscribed.find(a_which) != cloud::subscribed.end())
Finally, how certain are you that it's throwing an out of bounds exception and not another exception?
While reviewing some code, I found a piece of code like that:
struct MyFooStructure
{
//Nothing unusual, just basic types
}
class Foo : public QObject
{
Q_Object
public:
void fooMethod(const MyStructure &s);
signals:
void fooSignal(const MyStructure &);
}
void Foo::fooMethod(const MyStructure &s)
{
try
{
emit fooSignal(s)
}
catch(const std::exception &e)
{
qDebug() << "An exception!";
}
}
Is there any possibility to enter on the catch here? As far as I know, there are no possible exception being thrown: emit is just a macro to create a table to call the appropriate functions connected to that signal on the *.moc file. Is that try catch really needed?
Yes, the catch is needed in your example, at least if any slots connected to fooSignal throw an std::exception.
The statement emit fooSignal(); calls all connected slots synchronously. Basically QObject internally has a connection table in which it stores all connections for an object, which each slot being a function pointer. Basically what emit does (or rather, what the moc-generated implementation of fooSignal does) is that it simply iterates over the connection table and calls all function pointers for each connected slot.
So the slots are called from within the connect statement. That also means if any slots throw an exception, the exception will propagate outside of the emit statement.
Note that the internal moc-generated code for fooSignal is only exception-safe as of recent, see Olivier's answer on this bug report. That means older versions of Qt can't deal with exceptions being thrown in slots, and the moc-generated code will fail in undefined ways if slots throw an exception.
EDIT: I also want to add that having slots that throw exceptions is bad practice, try avoiding that. The code that calls emit doesn't know what slots are connected, so it doesn't know what exceptions it needs to catch. Furthermore, as soon as you have queued connections instead of direct connections, the slots will be called asynchronously instead of synchronously, and you won't be able to catch the slots' exceptions.
I am new to programming and am having trouble with try / catch clauses.
Here is an example from a textbook that I have:
int main( )
{
char *ptr;
try {
ptr = new char[ 1000000000 ];
}
catch( … ) {
cout << "Too many elements" << endl;
}
return 0;
}
I have tried to look online for a further explanation and the textbook does not exactly tell me what what these clauses actually do or what it is used for.
Any information would be helpful.
EDIT: The textbook I am using is:
C++: Classes and Data Structures by Jeffrey Childs
A try-catch is the C++ construct for exception handling. Google 'C++ exceptions'.
Try catch is a way of handling exceptions:
try
{
// Do work in here
// If any exceptions are generated then the code in here is stopped.
// and a jump is made to the catch block.
// to see if the exception can be handled.
// An exception is generated when somebody uses throw.
// Either you or one of the functions you call.
// In your case new can throw std::bad_alloc
// Which is derived from std::runtime_error which is derived from std::exception
}
// CATCH BLOCK HERE.
The catch block is where you define what exceptions you want to handle.
// CATCH BLOCK
catch(MyException const& e)
{
// Correct a MyException
}
catch(std::exception const& e)
{
// Correct a std::exception
// For example this would cat any exception derived from std::exception
}
You can have as many catch blocks as you like. If you exception matches any of the catch expressions in the catch statement then the associated block of code is executed. If no catch expressions matches an exception then the stack is unwound until it finds a higher level catch block and the processes is repeated (this can cause the application to exit if no matching catch block is found).
Note: If multiple catch expressions match then the lexically first one is used. Only one or none of the catch blocks will be executed. If none then the compiler will look for a higher level try/catch.
There is also a catch anything clause
catch(...)
{
// This is a catch all.
// If the exception is not listed above this will catch any exception.
}
So how does this apply to your code.
int main( )
{
char *ptr;
try
{
// This calls ::new() which can potentially throw std::bad_alloc
// If this happens then it will look for a catch block.
ptr = new char[ 1000000000 ];
// If the ::new() works then nothing happens and you pointer `ptr`
// is valid and code continues to execute.
}
catch( … )
{
// You only have one catch block that catches everything.
// So if there are any statements that generate an exception this will catch
// the excetption and execute this code.
cout << "Too many elements" << endl;
}
// As you have caught all exceptions the code will continue from here.
// Either after the try block finishes successfully or
// After an exception has been handled by the catch block.
return 0;
}
Try-catch blocks are used to trap errors in the code.
At the most basic level, errors occur because the program tries to execute an invalid instruction. That instruction (read: line of code) could be invalid for a number of reasons. In your specific instance, the instruction could be invalid if your program was not able to allocate 1,000,000,000 bytes of memory to story your ptr. The most common exception is trying to access a bad pointer, which is called a Null Pointer Exception, which occurs when you try to perform some action on an Object that either has not been created, or has been deleted (or got corrupt). You will learn to hate that exception.
Using catch(...) tells the program to execute the code inside the catch block if any error occurs inside the code within the try block. There you can handle your error and try to find someway to either fix the error condition or gracefully exit that module.
You can also catch specific errors, which you can find out more about here : http://www.cplusplus.com/doc/tutorial/exceptions/
If you already know C, try/catch achieves the same thing as setjmp/longjmp when used for error handling. Think of try as code for the if condition of setjmp and catch code for else of setjmp. This makes longjmp equivalent to throw in C++, which is used to throw an exception. In your example, probably, the new operator, which calls some memory allocation function internally, throws an exception on seeing a very large number as input by using the C++ throw operator.
void a()
{
.......
longjmp(buf,1); // <--- similar to throw
.......
}
if ( !setjmp(buf) ) // <--- similar to try
{
.......
a();
.......
}
else // <--- similar to catch
{
.......
}
try/catch is a bit more sophisticated than setjmp/longjmp, as for setjmp/longjmp you will need to declare variables which are modified in between setjmp/longjmp calls as volatile, which is not necessary for try/catch.