think about this:
StreamReader reader = null;
try
{
reader = new StreamReader(_fileName);
}
catch
{
//show error that file not found
reader.Dispose();
return false;
}
try
{
//code to read file
}
catch
{
//show error badly formed file
}
finally
{
reader.Dispose();
}
//return
the code above does not work when file can't be opened because it calls Dispose for null which results in exception.
i don't want to use using because i want to separate problems with opening the file and reading it. This could be achieved with million different catches but i don't want to go that way. Plus if using is same as try-finally would "hidden Dispose" throw an unwanted exception anyway? which would be the best way when all i need is to catch an exception opening it and an exception reading it?
Thanks & BR - Matti
It is better to use the using statement:
using(StreamReader reader = new StreamReader(_fileName))
{
}
The compiler will create the correct dispose semantics for you.
And you can still use try with this, not worrying about disposing it yourself:
try
{
using(StreamReader reader = new StreamReader(_fileName))
{
try
{
//code to read the file
}
catch
{
//show error badly formed file
}
}
}
catch
{
// show error that file not found
}
Your code is correct if you check reader for null before calling any methods on it, whereever that reader is located.
Using statement is not mandatory but is desirable.
You should check whether the reader is null before you dispose it. Like so:
StreamReader reader = null;
try
{
//code to read file
}
catch
{
//show error badly formed file
}
finally
{
if( null != reader )
{
reader.Dispose();
}
}
The StreamReader can throw the following exceptions so you could just handle these accordingly:-
ArgumentException
ArgumentNullException
FileNotFoundException
DirectoryNotFoundException
NotSupportedException
ArgumentOutOfRangeException
Related
The SignalR docs on streaming state:
Wrap logic in a try ... catch statement. Complete the Channel in a finally block. If you want to flow an error, capture it inside the catch block and write it in the finally block.
They then proceed to give an example that goes through these convolutions for no apparent gain. Why is this? What difference does it make whether one captures an exception and completes the channel from the finally block versus completing then and there in the catch block?
Possibly to centralize the writer completion logic, even if takes just a single invocation - and you may want to insert additional related logic there (such as logging), if needed.
Exception localException = null;
try
{
// ...
}
catch (Exception ex)
{
localException = ex;
}
finally
{
writer.Complete(localException);
}
versus:
var completed = false;
try
{
// ...
}
catch (Exception ex)
{
writer.Complete(ex);
completed = true;
}
finally
{
if (!completed)
{
writer.Complete(null);
}
}
I have been pulling my hair out with this one.
I have a very simple test class that throws this error:
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
System.Text.Json.JsonException: A possible object cycle was detected. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32. Consider using ReferenceHandler.Preserve on JsonSerializerOptions to support cycles.
It doesn't seem to break much, as the put request is successful and the serialize is also successful.
EDIT
I have chased the serialize exception out if it was ever really there. I am starting to think it is a problem with typed HttpClient. It throws the exception that comes out on the console and in the response on Postman. However, it doesn't allow me to catch the exception in the code and the PUT call works. So the exception is happening after the PUT request and is handled before it returns control to my app.
I am going to try to use a standard HttpClientFactor instead of a typed client and see if that works. I know that the JSON exception is a red herring, but it is ugly and breaking the response.
Any suggestions would be welcome.
public virtual async Task<CouchResponse> Create(string id, string db, TObj info)
{
CouchResponse ret = new() { Reason = "Unknown and unExpected error", Ok = false };
HttpResponseMessage rc = null;
if (id is null)
{
return new CouchResponse() { Id = "missing", Ok = false, Rev = "missing" };
}
string url = $"{db}/1";
try
{
// login to Couchdb servwer
await CouchLogin();
try
{
//var jsonInfo = JsonUtils.Serialize<TestJson>(jTest);
var jsonInfo = JsonSerializer.Serialize<TObj>(info, options);
HttpContent content = new StringContent(jsonInfo, Encoding.UTF8,
"application/json");
rc = await client.PutAsync(url, content);
}
catch (Exception eNewton)
{
Console.WriteLine($"Json Exception: {eNewton.Message}");
}
if (rc is not null)
{
var str = await rc.Content.ReadAsStringAsync();
var ret = JsonSerializer.Deserialize<CouchResponse>(str,options);
rc.EnsureSuccessStatusCode();
}
return ret;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
//return ret;
}
return ret;
}
Suggestions?
What a crazy bug. The diagnostic was very missing leading. Everything I was doing in the create method was correct.
What is missed was an await when I called the create method. This made it appear that the sendAsync was having the issue when it was really the controller trying to format the task return as a response. This caused the stack trace in the response message. Thanks for all the help.
Change this
var jsonSerializerSettings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
NullValueHandling = NullValueHandling.Ignore
};
To this
var jsonSerializerSettings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
NullValueHandling = NullValueHandling.Ignore,
MaxDepth = null,
};
I am using java 8 stream and I can not throw the exceptions inside the foreach of stream.
stream.forEach(m -> {
try {
if (isInitial) {
isInitial = false;
String outputName = new SimpleDateFormat(Constants.HMDBConstants.HMDB_SDF_FILE_NAME).format(new Date());
if (location.endsWith(Constants.LOCATION_SEPARATOR)) {
savedPath = location + outputName;
} else {
savedPath = location + Constants.LOCATION_SEPARATOR + outputName;
}
File output = new File(savedPath);
FileWriter fileWriter = null;
fileWriter = new FileWriter(output);
writer = new SDFWriter(fileWriter);
}
writer.write(m);
} catch (IOException e) {
throw new ChemIDException(e.getMessage(),e);
}
});
and this is my exception class
public class ChemIDException extends Exception {
public ChemIDException(String message, Exception e) {
super(message, e);
}
}
I am using loggers to log the errors in upper level. So I want to throw the exception to top. Thanks
Try extending RuntimeException instead. The method that is created to feed to the foreach does not have that type as throwable, so you need something that is runtime throwable.
WARNING: THIS IS PROBABLY NOT A VERY GOOD IDEA
But it will probably work.
Why are you using forEach, a method designed to process every element, when all you want to do, is to process the first element? Instead of realizing that forEach is the wrong method for the job (or that there are more methods in the Stream API than forEach), you are kludging this with an isInitial flag.
Just consider:
Optional<String> o = stream.findFirst();
if(o.isPresent()) try {
String outputName = new SimpleDateFormat(Constants.HMDBConstants.HMDB_SDF_FILE_NAME)
.format(new Date());
if (location.endsWith(Constants.LOCATION_SEPARATOR)) {
savedPath = location + outputName;
} else {
savedPath = location + Constants.LOCATION_SEPARATOR + outputName;
}
File output = new File(savedPath);
FileWriter fileWriter = null;
fileWriter = new FileWriter(output);
writer = new SDFWriter(fileWriter);
writer.write(o.get());
} catch (IOException e) {
throw new ChemIDException(e.getMessage(),e);
}
which has no issues with exception handling. This example assumes that the Stream’s element type is String. Otherwise, you have to adapt the Optional<String> type.
If, however, your isInitial flag is supposed to change more than once during the stream processing, you are definitely using the wrong tool for your job. You should have read and understood the “Stateless behaviors” and “Side-effects” sections of the Stream API documentation, as well as the “Non-interference” section, before using Streams. Just converting loops to forEach invocations on a Stream doesn’t improve the code.
I'm trying to write and read to local storage for Win8. Using a helper I am able to successfully write to my machine, but reading the .xml file gives me a: System.UnauthorizedAccessException occurred in mscorlib.dll error
I created a codepaste so you can see my code.
http://codepaste.net/k9mht5
The code is failing here:
public async static Task<object> LoadData(string path, System.Type type)
{
var _Folder = Windows.Storage.ApplicationData.Current.LocalFolder;
try
{
var _File = await Folder.GetFileAsync(path);
using (IInputStream inStream = await _File.OpenSequentialReadAsync())
{
// Deserialize the Session State
XmlSerializer x = new XmlSerializer(type);
return x.Deserialize(inStream.AsStreamForRead());
}
}
catch (Exception ex)
{
MessageDialog dialog = new MessageDialog(ex.Message.ToString());
dialog.ShowAsync();
return null;
}
}
Specifically on this line:
using (IInputStream inStream = await _File.OpenSequentialReadAsync())
If you have any ideas on what I am doing incorrectly it would help me out a lot.
I am doing this in Release Preview. If there is any other system information I need to give, please let me know.
Ok, here is what I've noticed. In file vehicleViewModel.cs you call SaveList(); and GetList(); one after another. Both of these methods are declared as async void which means fire and forget. My idea is that while SaveList is trying to save, GetList is trying to read one file at the same time. I tried your code and I got the same error too. Try to change SaveList and GetList methods to be async Task and then use await:
await SaveList();
await GetList();
That did the trick for me.
Use the dispatcher it will solve your problem
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
{
// Your UI update code goes here!
_dialogService.ShowMessage(rdm.ErrorMessage);
});
I am having a rough time trying to wrap my head around the Lucene library. This is what I have so far:
public void shingleMe()
{
try
{
StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_35);
FileReader reader = new FileReader("test.txt");
ShingleAnalyzerWrapper shingleAnalyzer = new ShingleAnalyzerWrapper(analyzer, 2);
shingleAnalyzer.setOutputUnigrams(false);
TokenStream stream = shingleAnalyzer.tokenStream("contents", reader);
CharTermAttribute charTermAttribute = stream.getAttribute(CharTermAttribute.class);
while (stream.incrementToken())
{
System.out.println(charTermAttribute.toString());
}
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
It fails at stream.incrementToken(). It's my understanding that the ShingleAnalyzerWrapper uses another Analyzer to create a shingle analyzer object. From there, I convert it to a token stream which is then parsed using an attribute filter. However, it always results in this exception:
Exception in thread "main" java.lang.AbstractMethodError: org.apache.lucene.analysis.TokenStream.incrementToken()Z
Thoughts? Thanks in advance!
AbstractMethodError cannot occur as a result of wrong API usage -- it must be the result of compiling against one JAR and then running against a different one. Since you are using both Lucene Core and Lucene Analyzers JAR here, double-check your compile-time and runtime JAR classpaths.