Closed endizhupani closed 1 year ago
@endizhupani Can you share the full stack trace of the null reference exception you are getting. I am not able to replicate the NRE when using the ReadAsStringAsync
extension method. If you may also share the code you used to replicate the issue, that would be great.
The ReadAsStringAsync
method uses StreamReader
constructor and if an encoding value is not passed as a parameter to this constructor, it will use the default value which is UTF8.
@kshyju Of course. Just for further info, the target framework for my functions project is net48, so I'm using .NET Framework.
Stack trace (timestamps are there because I copied the function logs directly):
Function 'worftopdfconversion', Invocation id 'acb921dc-68d5-4cf5-8cb6-aebcbe133f11': An exception was thrown by the invocation.
[2023-10-25T07:29:12.625Z] Result: Function 'worftopdfconversion', Invocation id 'acb921dc-68d5-4cf5-8cb6-aebcbe133f11': An exception was thrown by the invocation.
Exception: System.AggregateException: One or more errors occurred. ---> System.ArgumentNullException: Value cannot be null.
[2023-10-25T07:29:12.626Z] Parameter name: encoding
[2023-10-25T07:29:12.626Z] at System.IO.StreamReader..ctor(Stream stream, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize, Boolean leaveOpen)
[2023-10-25T07:29:12.627Z] at Microsoft.Azure.Functions.Worker.Http.HttpRequestDataExtensions.<ReadAsStringAsync>d__0.MoveNext() in D:\a\_work\1\s\src\DotNetWorker.Core\Http\HttpRequestDataExtensions.cs:line 40
[2023-10-25T07:29:12.628Z] --- End of stack trace from previous location where exception was thrown ---
[2023-10-25T07:29:12.629Z] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
[2023-10-25T07:29:12.630Z] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
[2023-10-25T07:29:12.630Z] at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
[2023-10-25T07:29:12.631Z] at Crm.WordToPdfConversion.FileConverter.<Run>d__2.MoveNext() in C:\Users\endi.zhupani\source\repos\Ximea.Services\src\legacy\Crm.WordToPdfConversion\FileConverter.cs:line 33
[2023-10-25T07:29:12.632Z] --- End of inner exception stack trace ---
[2023-10-25T07:29:12.633Z] at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
[2023-10-25T07:29:12.634Z] at Microsoft.Azure.Functions.Worker.Invocation.DefaultFunctionInvoker`2.<>c.<InvokeAsync>b__6_0(Task`1 t) in D:\a\_work\1\s\src\DotNetWorker.Core\Invocation\DefaultFunctionInvoker.cs:line 32
[2023-10-25T07:29:12.635Z] at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
[2023-10-25T07:29:12.636Z] at System.Threading.Tasks.Task.Execute()
[2023-10-25T07:29:12.636Z] --- End of stack trace from previous location where exception was thrown ---
[2023-10-25T07:29:12.637Z] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
[2023-10-25T07:29:12.638Z] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
[2023-10-25T07:29:12.639Z] at Microsoft.Azure.Functions.Worker.Invocation.DefaultFunctionExecutor.<ExecuteAsync>d__4.MoveNext() in D:\a\_work\1\s\src\DotNetWorker.Core\Invocation\DefaultFunctionExecutor.cs:line 45
[2023-10-25T07:29:12.640Z] --- End of stack trace from previous location where exception was thrown ---
[2023-10-25T07:29:12.641Z] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
[2023-10-25T07:29:12.642Z] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
[2023-10-25T07:29:12.642Z] at Microsoft.Azure.Functions.Worker.OutputBindings.OutputBindingsMiddleware.<Invoke>d__0.MoveNext() in D:\a\_work\1\s\src\DotNetWorker.Core\OutputBindings\OutputBindingsMiddleware.cs:line 15
[2023-10-25T07:29:12.643Z] --- End of stack trace from previous location where exception was thrown ---
[2023-10-25T07:29:12.644Z] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
[2023-10-25T07:29:12.645Z] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
[2023-10-25T07:29:12.645Z] at Microsoft.Azure.Functions.Worker.FunctionsApplication.<InvokeFunctionAsync>d__10.MoveNext() in D:\a\_work\1\s\src\DotNetWorker.Core\FunctionsApplication.cs:line 77
[2023-10-25T07:29:12.646Z] ---> (Inner Exception #0) System.ArgumentNullException: Value cannot be null.
[2023-10-25T07:29:12.647Z] Parameter name: encoding
[2023-10-25T07:29:12.648Z] at System.IO.StreamReader..ctor(Stream stream, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize, Boolean leaveOpen)
[2023-10-25T07:29:12.648Z] at Microsoft.Azure.Functions.Worker.Http.HttpRequestDataExtensions.<ReadAsStringAsync>d__0.MoveNext() in D:\a\_work\1\s\src\DotNetWorker.Core\Http\HttpRequestDataExtensions.cs:line 40
[2023-10-25T07:29:12.649Z] --- End of stack trace from previous location where exception was thrown ---
[2023-10-25T07:29:12.650Z] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
[2023-10-25T07:29:12.651Z] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
[2023-10-25T07:29:12.651Z] at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
[2023-10-25T07:29:12.652Z] at Crm.WordToPdfConversion.FileConverter.<Run>d__2.MoveNext() in C:\Users\endi.zhupani\source\repos\Ximea.Services\src\legacy\Crm.WordToPdfConversion\FileConverter.cs:line 33<---
[2023-10-25T07:29:12.653Z]
Stack: at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
[2023-10-25T07:29:12.654Z] at Microsoft.Azure.Functions.Worker.Invocation.DefaultFunctionInvoker`2.<>c.<InvokeAsync>b__6_0(Task`1 t) in D:\a\_work\1\s\src\DotNetWorker.Core\Invocation\DefaultFunctionInvoker.cs:line 32
[2023-10-25T07:29:12.655Z] at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
[2023-10-25T07:29:12.655Z] at System.Threading.Tasks.Task.Execute()
[2023-10-25T07:29:12.656Z] --- End of stack trace from previous location where exception was thrown ---
[2023-10-25T07:29:12.657Z] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
[2023-10-25T07:29:12.658Z] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
[2023-10-25T07:29:12.658Z] at Microsoft.Azure.Functions.Worker.Invocation.DefaultFunctionExecutor.<ExecuteAsync>d__4.MoveNext() in D:\a\_work\1\s\src\DotNetWorker.Core\Invocation\DefaultFunctionExecutor.cs:line 45
[2023-10-25T07:29:12.656Z] Executed 'Functions.worftopdfconversion' (Failed, Id=acb921dc-68d5-4cf5-8cb6-aebcbe133f11, Duration=4924ms)
[2023-10-25T07:29:12.659Z] --- End of stack trace from previous location where exception was thrown ---
[2023-10-25T07:29:12.660Z] System.Private.CoreLib: Exception while executing function: Functions.worftopdfconversion. System.Private.CoreLib: Result: Failure
Exception: System.AggregateException: One or more errors occurred. ---> System.ArgumentNullException: Value cannot be null.
[2023-10-25T07:29:12.661Z] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
[2023-10-25T07:29:12.662Z] Parameter name: encoding
[2023-10-25T07:29:12.662Z] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
[2023-10-25T07:29:12.663Z] at System.IO.StreamReader..ctor(Stream stream, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize, Boolean leaveOpen)
[2023-10-25T07:29:12.664Z] at Microsoft.Azure.Functions.Worker.Http.HttpRequestDataExtensions.<ReadAsStringAsync>d__0.MoveNext() in D:\a\_work\1\s\src\DotNetWorker.Core\Http\HttpRequestDataExtensions.cs:line 40
[2023-10-25T07:29:12.664Z] at Microsoft.Azure.Functions.Worker.OutputBindings.OutputBindingsMiddleware.<Invoke>d__0.MoveNext() in D:\a\_work\1\s\src\DotNetWorker.Core\OutputBindings\OutputBindingsMiddleware.cs:line 15
[2023-10-25T07:29:12.665Z] --- End of stack trace from previous location where exception was thrown ---
[2023-10-25T07:29:12.666Z] --- End of stack trace from previous location where exception was thrown ---
[2023-10-25T07:29:12.666Z] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
[2023-10-25T07:29:12.667Z] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
[2023-10-25T07:29:12.668Z] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
[2023-10-25T07:29:12.669Z] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
[2023-10-25T07:29:12.669Z] at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
[2023-10-25T07:29:12.670Z] at Microsoft.Azure.Functions.Worker.FunctionsApplication.<InvokeFunctionAsync>d__10.MoveNext() in D:\a\_work\1\s\src\DotNetWorker.Core\FunctionsApplication.cs:line 77.
[2023-10-25T07:29:12.671Z] at Crm.WordToPdfConversion.FileConverter.<Run>d__2.MoveNext() in C:\Users\endi.zhupani\source\repos\Ximea.Services\src\legacy\Crm.WordToPdfConversion\FileConverter.cs:line 33
[2023-10-25T07:29:12.672Z] --- End of inner exception stack trace ---
[2023-10-25T07:29:12.673Z] at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
[2023-10-25T07:29:12.673Z] at Microsoft.Azure.Functions.Worker.Invocation.DefaultFunctionInvoker`2.<>c.<InvokeAsync>b__6_0(Task`1 t) in D:\a\_work\1\s\src\DotNetWorker.Core\Invocation\DefaultFunctionInvoker.cs:line 32
[2023-10-25T07:29:12.674Z] at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
[2023-10-25T07:29:12.675Z] at System.Threading.Tasks.Task.Execute()
[2023-10-25T07:29:12.676Z] --- End of stack trace from previous location where exception was thrown ---
[2023-10-25T07:29:12.676Z] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
[2023-10-25T07:29:12.677Z] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
[2023-10-25T07:29:12.678Z] at Microsoft.Azure.Functions.Worker.Invocation.DefaultFunctionExecutor.<ExecuteAsync>d__4.MoveNext() in D:\a\_work\1\s\src\DotNetWorker.Core\Invocation\DefaultFunctionExecutor.cs:line 45
[2023-10-25T07:29:12.679Z] --- End of stack trace from previous location where exception was thrown ---
[2023-10-25T07:29:12.679Z] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
[2023-10-25T07:29:12.680Z] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
[2023-10-25T07:29:12.681Z] at Microsoft.Azure.Functions.Worker.OutputBindings.OutputBindingsMiddleware.<Invoke>d__0.MoveNext() in D:\a\_work\1\s\src\DotNetWorker.Core\OutputBindings\OutputBindingsMiddleware.cs:line 15
[2023-10-25T07:29:12.681Z] --- End of stack trace from previous location where exception was thrown ---
[2023-10-25T07:29:12.682Z] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
[2023-10-25T07:29:12.683Z] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
[2023-10-25T07:29:12.684Z] at Microsoft.Azure.Functions.Worker.FunctionsApplication.<InvokeFunctionAsync>d__10.MoveNext() in D:\a\_work\1\s\src\DotNetWorker.Core\FunctionsApplication.cs:line 85
[2023-10-25T07:29:12.685Z] --- End of stack trace from previous location where exception was thrown ---
[2023-10-25T07:29:12.686Z] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
[2023-10-25T07:29:12.686Z] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
[2023-10-25T07:29:12.687Z] at Microsoft.Azure.Functions.Worker.Handlers.InvocationHandler.<InvokeAsync>d__8.MoveNext() in D:\a\_work\1\s\src\DotNetWorker.Grpc\Handlers\InvocationHandler.cs:line 90
[2023-10-25T07:29:12.688Z] ---> (Inner Exception #0) System.ArgumentNullException: Value cannot be null.
[2023-10-25T07:29:12.688Z] Parameter name: encoding
[2023-10-25T07:29:12.689Z] at System.IO.StreamReader..ctor(Stream stream, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize, Boolean leaveOpen)
[2023-10-25T07:29:12.690Z] at Microsoft.Azure.Functions.Worker.Http.HttpRequestDataExtensions.<ReadAsStringAsync>d__0.MoveNext() in D:\a\_work\1\s\src\DotNetWorker.Core\Http\HttpRequestDataExtensions.cs:line 40
[2023-10-25T07:29:12.691Z] --- End of stack trace from previous location where exception was thrown ---
[2023-10-25T07:29:12.692Z] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
[2023-10-25T07:29:12.693Z] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
[2023-10-25T07:29:12.693Z] at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
[2023-10-25T07:29:12.694Z] at Crm.WordToPdfConversion.FileConverter.<Run>d__2.MoveNext() in C:\Users\endi.zhupani\source\repos\Ximea.Services\src\legacy\Crm.WordToPdfConversion\FileConverter.cs:line 33<---
[2023-10-25T07:29:12.695Z]
Stack: at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
[2023-10-25T07:29:12.695Z] at Microsoft.Azure.Functions.Worker.Invocation.DefaultFunctionInvoker`2.<>c.<InvokeAsync>b__6_0(Task`1 t) in D:\a\_work\1\s\src\DotNetWorker.Core\Invocation\DefaultFunctionInvoker.cs:line 32
[2023-10-25T07:29:12.696Z] at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
[2023-10-25T07:29:12.697Z] at System.Threading.Tasks.Task.Execute()
[2023-10-25T07:29:12.697Z] --- End of stack trace from previous location where exception was thrown ---
[2023-10-25T07:29:12.698Z] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
[2023-10-25T07:29:12.699Z] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
[2023-10-25T07:29:12.700Z] at Microsoft.Azure.Functions.Worker.Invocation.DefaultFunctionExecutor.<ExecuteAsync>d__4.MoveNext() in D:\a\_work\1\s\src\DotNetWorker.Core\Invocation\DefaultFunctionExecutor.cs:line 45
[2023-10-25T07:29:12.701Z] --- End of stack trace from previous location where exception was thrown ---
[2023-10-25T07:29:12.701Z] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
[2023-10-25T07:29:12.702Z] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
[2023-10-25T07:29:12.703Z] at Microsoft.Azure.Functions.Worker.OutputBindings.OutputBindingsMiddleware.<Invoke>d__0.MoveNext() in D:\a\_work\1\s\src\DotNetWorker.Core\OutputBindings\OutputBindingsMiddleware.cs:line 15
[2023-10-25T07:29:12.703Z] --- End of stack trace from previous location where exception was thrown ---
[2023-10-25T07:29:12.704Z] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
[2023-10-25T07:29:12.705Z] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
[2023-10-25T07:29:12.706Z] at Microsoft.Azure.Functions.Worker.FunctionsApplication.<InvokeFunctionAsync>d__10.MoveNext() in D:\a\_work\1\s\src\DotNetWorker.Core\FunctionsApplication.cs:line 85
[2023-10-25T07:29:12.707Z] --- End of stack trace from previous location where exception was thrown ---
[2023-10-25T07:29:12.707Z] at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
[2023-10-25T07:29:12.708Z] at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
[2023-10-25T07:29:12.709Z] at Microsoft.Azure.Functions.Worker.Handlers.InvocationHandler.<InvokeAsync>d__8.MoveNext() in D:\a\_work\1\s\src\DotNetWorker.Grpc\Handlers\InvocationHandler.cs:line 90.
Function Code:
using Aspose.Words;
using Aspose.Words.Fonts;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;
using System;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using System.Web.Helpers;
namespace Crm.WordToPdfConversion
{
public class FileConverter
{
private readonly ILogger _logger;
public FileConverter(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<FileConverter>();
}
[Function("wordtopdfconversion")]
public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequestData req)
{
_logger.LogInformation("wordtopdfconversion: C# HTTP trigger function processed a request.");
string base64 = req.Query["doc"];
if (base64 == null)
{
// Get request body
var data = Json.Decode(await req.ReadAsStringAsync().ConfigureAwait(false));
base64 = data?.base64;
}
if (base64 != null)
{
License l = new License();
l.SetLicense(@"Aspose.Words.lic");
if (!l.IsLicensed)
{
throw new InvalidOperationException("License has expired for PDF conversion.");
}
MemoryStream input = new MemoryStream(Convert.FromBase64String(base64));
input.Flush();
input.Seek(0, SeekOrigin.Begin);
MemoryStream output = new MemoryStream();
MemoryFontSource font = new MemoryFontSource(Convert.FromBase64String(Base64Font));
FontSourceBase[] fonts = { font };
Document doc = new Document(input);
FontSettings.DefaultInstance.SetFontsSources(fonts);
doc.Save(output, SaveFormat.Pdf);
output.Flush();
output.Seek(0, SeekOrigin.Begin);
base64 = Convert.ToBase64String(output.ToArray());
input.Dispose();
output.Dispose();
}
if (base64 == null)
{
var response = req.CreateResponse(HttpStatusCode.BadRequest);
response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
response.WriteString("Please pass data on the query string or in the request body");
return response;
}
else
{
var response = req.CreateResponse(HttpStatusCode.OK);
response.Headers.Add("Content-Type", "text/plain; charset=utf-8");
response.WriteString(base64);
return response;
}
}
private const string Base64Font = "base64string";
}
}
Just for further info, the target framework for my functions project is net48, so I'm using .NET Framework.
@endizhupani thank you for sharing this. It could potentially be something specific to .NET Framework, but @kshyju is correct and I would expect the behavior here to be consistent with the behavior exposed by the StreamReader
constructor we use.
The only scenario I'd expect the behavior you're seeing is if the stream is using an encoding that couldn't be inferred by the StreamReader
@fabiocav I dug a bit deeper into this. Looking at the stack trace it seems like the NRE is being thrown from directly inside the StreamReader
constructor. Does it look at the stream to infer the encoding already while being constructed?
Looking at the dependencies of DotNetWorker.Core, it seems to have net5.0
and netstandard2.0
. I'm a bit unclear on this: do they have the same implementation of StreamReader
, or each its own?
I had a look at the source code of the StreamReader
constructor in net5.0
and I don't see any logic there which infers the encoding. I also saw the following at the beginning of the constructors body:
if (encoding == null)
{
encoding = Encoding.UTF8;
}
So the NRE should not be thrown.
Since my function app runs on .NET Framework, I'm assuming that the implementation used is the one from netstandard2.0
. I can't look at the source code but could it be that this implementation actually does not allow null
? Looking at the signature from the screenshot above, the Encoding
param is not market as nullable for the netstandard
version.
Thanks @endizhupani Yes, you are correct, in .netframework, the StreamReader constructor throws when encoding
parameter is null
. In net6+, it sets the default value UTF8) if the parameter value is null.
I will take a look at your PR with the fix. Thank you for reporting the issue and opening a PR to fix it.
Indeed. We'll continue to iterate on the PR, but the changes are reasonable.
Issue: Calling
Microsoft.Azure.Functions.Worker.Http.HttpRequestDataExtensions.ReadAsStringAsync
without specifying the encoding results in aNullReferenceException
.The documentation for
HttpRequestDataExtensions.ReadAsStringAsync
states that theencoding
parameter defaults to UTF-8.Expected behaviour A call such as this:
await req.ReadAsStringAsync()
works and UTF-8 as the default encoding.