.NET Core - how to catch a StackOverflowException - exception

The perfect StackOverflow question has finally come....
How do I catch a StackOverflow exception!
It seems in .NET Core the StackOverflowException isn't available:
And if I run this code:
using System;
namespace PlayGround.Core.Console
{
public class Program
{
public static void Main(string[] args)
{
try
{
DoSomething();
}
catch(Exception e)
{
System.Console.WriteLine("Bugger");
}
}
private static void DoSomething()
{
DoSomething();
}
}
}
I get this:
You can see my exception handler didn't run. So how do I go about catching this exception in .NET Core?
EDIT September 15th, 2017:
In .NET Core 2.0 there is now a StackOverflowException class, but it still doesn't actually catch a stackoverflow exception.

Since CLR 2.0 you cant catch a StackOverflowException. Unless you were the one to throw it it.
https://blogs.msdn.microsoft.com/jaredpar/2008/10/22/when-can-you-catch-a-stackoverflowexception/

Related

Why it is throwing compile time error?

Why this program throwing compile time error even though I have declared Ari class which extends Exception class.It is giving me output like "unreported exception Ari; must be caught or declared to be thrown".
class Ari extends Exception{ }
public class Main
{
public static void main(String [] args)
{
try
{
badMethod();
System.out.print("A");
}
catch (Exception ex)
{
System.out.print("B");
}
finally
{
System.out.print("C ");
}
System.out.print("D");
}
public static void badMethod()
{
throw new Ari(); /* Line 22 */
}
}
This looks like Java, which uses "checked exceptions". Since your method can throw an Ari exception (in fact, it's guaranteed to), the method signature must declare this:
public static void badMethod() throws Ari {
throw new Ari();
}
This advises consuming code of the possibility of this specific exception so that it can be written to handle that exception.

Where can I get the exception throwed within the subscribe() method?

I'm using rxAndroid.
I've read many documents, but still not found the solution, and maybe I missed it,
so please give me a guide.
Here I created an observable that might throw an exception in subscribe method.
return Observable.create(new ObservableOnSubscribe<Project>() {
#Override
public void subscribe(#NonNull ObservableEmitter<Project> e) throws Exception {
e.onNext(projectRepository.readDetails(project.getId()));
e.onComplete();
}
});
I use repository pattern to get the project details,
but the problem is all of the repository methods might throw an exception,
projectRepository.readDetails(project.getId())
And I couldn't find anyway to handle the exception throwed in the method subscibe(), Observer's onError() will not get any notification of it.
Thanks.
When creating an observable manually, you have to catch any exception and pass them to the onError() manually:
return Observable.create(new ObservableOnSubscribe<Project>() {
#Override
public void subscribe(#NonNull ObservableEmitter<Project> e) throws Exception {
try {
e.onNext(projectRepository.readDetails(project.getId()));
e.onComplete();
}
catch (Exception ex) {
e.onError(ex);
}
}
});
Alternatively you should be able to use fromCallable() to avoid having to create the observable manually:
Observable.fromCallable(() -> projectRepository.readDetails(project.getId()));
This will signal onError() if the call should fail.

Using MockWebServer with Robolectric

I'm trying to unit test some API calls using MockWebServer and Robolectric.
My test class is annotated with:
#RunWith(RobolectricGradleTestRunner.class)
#Config(constants = BuildConfig.class, sdk = 23)
However when trying to build the Retrofit instance I get the following exception:
java.lang.NullPointerException
at android.os.Handler.__constructor__(Handler.java:229)
at android.os.Handler.<init>(Handler.java)
at retrofit2.Platform$Android$MainThreadExecutor.<init>(Platform.java:105)
at retrofit2.Platform$Android.defaultCallbackExecutor(Platform.java:97)
at retrofit2.Retrofit$Builder.build(Retrofit.java:556)
The code I'm using to build the retrofit instance:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(mMockServer.url(""))
.addConverterFactory(GsonConverterFactory.create())
.build();
The exception above is returned upon calling .build().
How do I fix this problem?
I had this same problem. There is a bug open about the underlying cause here but while that is ongoing, I settled for using Robolectric 3.0 and the solution outlined by dave-r12 here which is to create the mock I've included below.
#RunWith(RobolectricGradleTestRunner.class)
#Config(shadows = CreateOkHttpClientTest.MyNetworkSecurityPolicy.class)
public class CreateOkHttpClientTest {
#Test
...
#Implements(NetworkSecurityPolicy.class)
public static class MyNetworkSecurityPolicy {
#Implementation
public static NetworkSecurityPolicy getInstance() {
try {
Class<?> shadow = MyNetworkSecurityPolicy.class.forName("android.security.NetworkSecurityPolicy");
return (NetworkSecurityPolicy) shadow.newInstance();
} catch (Exception e) {
throw new AssertionError();
}
}
#Implementation
public boolean isCleartextTrafficPermitted() {
return true;
}
}
}
An alternate solution that seems to work is to just provide a dummy executor when setting up Retrofit
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://www.example.com/")
.client(client)
.callbackExecutor(new Executor() {
#Override
public void execute(Runnable command) {
//doesn't matter since tests are synchronous
}
})
.addConverterFactory(ScalarsConverterFactory.create())
.build();
It may be something that in the end needs to be corrected on the Retrofit side, somehow detecting if the current Platform is Robolectric and return a dummy executor or something.
If you are stuck on Robolectric 3 or below and you are targeting the API 25 the proper solution is almost the same like accepted one.
#Implements(NetworkSecurityPolicy.class)
public class NetworkSecurityPolicyShadow {
#Implementation
public static NetworkSecurityPolicy getInstance() {
try {
Class<?> shadow = Class.forName("android.security.NetworkSecurityPolicy");
return (NetworkSecurityPolicy) shadow.newInstance();
} catch (Exception e) {
throw new AssertionError();
}
}
#Implementation
public boolean isCleartextTrafficPermitted(String host) {
return true;
}
}
Only difference is in isCleartextTrafficPermitted(String host) because the OkHttp will try to call this method with host argument.
Could you try with sdk=21. I believe support for sdk=23 was added only from 3.1-SNAPSHOT and not release version.
Edit: I was wrong support was added from version 3.1 because I could successfully run a test
#RunWith(RobolectricGradleTestRunner.class)
#Config(constants = BuildConfig.class, sdk = 23)
public class ExampleUnitTest {
private MockWebServer mMockServer = new MockWebServer();
#Test
public void build_retrofit() throws Exception {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(mMockServer.url(""))
.addConverterFactory(GsonConverterFactory.create())
.build();
}
}
My gradle.build
testCompile 'junit:junit:4.12'
testCompile "org.robolectric:robolectric:3.1"
testCompile 'com.squareup.okhttp3:mockwebserver:3.3.0'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
Which libraries version are you using?

Junit testing forcing exception

I have the following method:
public Object method(){
try
{
privatevoidmethod1();
privatevoidmethod2();
}
catch(Exception e)
{
Log.debug(e);
}
return object;
}
How do I force the exception so I can test the debug call?
Leaving aside how you'd test the debug call, you'd normally trigger an exception by providing suitable inputs such that an exception would be created/thrown. If that's not suitable, the alternative is to provide a substitute (mocked) component that has been configured/written to throw an exception e.g.
public MyClass(MyInjectedComponent component) {
this.component = component;
}
and you'd provide for your test an implementation of MyInjectedComponent that will throw an exception (for testing purposes). The approach of injecting components into other components is called dependency injection and worth investigating.
I'd normally use a mocking framework for this (e.g. Mockito or similar). However a trivial implementation of the above could be:
public class MyImplementationForTesting extends MyInjectedComponent {
public void method() throws Exception {
throw new Exception();
}
}

What's the meaning of Proctectable interface in JUnit source code?

I'm recently digging into the source code of JUnit-4.11, what confuse me is that the seemingly redundant Protectable interface. the declaration is as follows:
public interface Protectable {
public abstract void protect() throws Throwable;
}
In the TestResult class, there is a void run(final TestCase test) method, in which a anonymous Protectable instance is realized as follows:
protected void run(final TestCase test) {
startTest(test);
Protectable p = new Protectable() {
public void protect() throws Throwable {
test.runBare();
}
};
runProtected(test, p);
endTest(test);
}
runProtected method is as follows:
public void runProtected(final Test test, Protectable p) {
try {
p.protect();
} catch (AssertionFailedError e) {
addFailure(test, e);
} catch (ThreadDeath e) { // don't catch ThreadDeath by accident
throw e;
} catch (Throwable e) {
addError(test, e);
}
}
As we can see, what runProtected does is just executing test.runBare();, so is there any sense to the existence of Protectable interface? Why can't we just write code like below.
protected void run(final TestCase test) {
startTest(test);
test.runBare();
endTest(test);
}
To answer your final question first, you can't use
protected void run(final TestCase test) {
startTest(test);
test.runBare();
endTest(test);
}
because it won't do what you want. JUnit manages asserts using exceptions, specifically AssertionFailedError. So, Assert.assertEquals() throws an AssertionFailedError when the two values aren't equal. So, in the above method, the endTest(test) won't get called if there is an assertion failure, which means the correct events (failure/error of the test) won't get fired, and tearDown() won't get executed.
The Protectable interface is there to give a more generic interface to the runner, so that you don't have to hand a TestCase to the method, to allow different actions.
As an aside, this is part of the package junit.framework.*, which is JUnit 3. JUnit 4 is where it's at, and if you want to learn, look more in the org.junit.* packages.
It seems to handle thrown exceptions in specific way :
Call addFailure for assertion exception (your test failed), addError for other exception (your test is not well coded)
This interface is to protect the TestCase by adding Throwable.
so junit could run any testcase safely.
The Throwable class is the superclass of all errors and exceptions in the Java language.