Skip to content

hiding error details discussion #10

@csantero

Description

@csantero

Continuing discussion from #8

Option 4 also occurred to me: if we have a hook where we allow the user to log an error (as we were saying), we could have that function return an error message: e.g. public HttpError processError(HttpError error) { ... }, in which case the user could return a different (e.g. redacted) error or null, if they wanted the error to not be serialized at all.

Although I do like option 4's approach of providing a hook to allow the user to log errors, using it for hiding error details doesn't seem right to me for the following reasons:

  1. We're already giving them the ability to change the rules for serializing HttpErrors via overriding ErrorSerializer (well, assuming we agree to do that).
  2. It's more work for the casual user to have to use that hook to hide the error details, when probably the vast majority of users would prefer to have this just taken care of for them.
  3. A user can already write their own ActionFilter that catches HttpErrors and massages them into something else, and stick it ahead of our filter(s) in the pipeline.

Code examples

  • Let jsonapi.net use GlobalConfiguration.Configuration.IncludeErrorDetailPolicy
    to determine whether to hide error details. No logging:
        var formatter = new JsonApiFormatter();
        config.Formatters.Clear();
        config.Formatters.Add(formatter);

        // Global filters
        config.Filters.Add(new JsonApiErrorHandlerActionFilterAttribute());
  • Use custom configuration to determine whether to hide error details. No logging:
        var formatter = new JsonApiFormatter();
        formatter.Configuration = new MyConfig();
        config.Formatters.Clear();
        config.Formatters.Add(formatter);

        // Global filters
        config.Filters.Add(new JsonApiErrorHandlerActionFilterAttribute());
class MyConfig : JsonApiFormatterConfiguration
{
    public override bool ShouldIncludeErrorDetail()
    {
        return true;
    }
}    
  • Override ErrorSerializer and perform custom handling there:
        var formatter = new JsonApiFormatter();
        formatter.ErrorSerializer = new MyErrorSerializer();
        config.Formatters.Clear();
        config.Formatters.Add(formatter);

        // Global filters
        config.Filters.Add(new JsonApiErrorHandlerActionFilterAttribute());
class MyErrorSerializer : IErrorSerializer
{
    public bool CanSerialize(Type type) { return true; }
    public void SerializeError(object error, Stream writeStream, JsonWriter writer, JsonSerializer serializer)
    {
        var httpError = error as HttpError;
        writer.WriteStartObject();
        writer.WritePropertyName("errorMessage");
        writer.WriteValue("I am going to completely disregard the spec and do something custom here.");
        writer.WriteEndObject();
    }
}
  • Log errors after they have been assigned a GUID by us:
        var formatter = new JsonApiFormatter();
        config.Formatters.Clear();
        config.Formatters.Add(formatter);

        // Global filters
        config.Filters.Add(new MyErrorHandlerActionFilterAttribute());
class MyErrorHandlerActionFilterAttribute : JsonApiErrorHandlerActionFilterAttribute
{
    public override Task LogError(HttpActionExecutedContext actionExecutedContext, HttpError error)
    {
        // error has a key of JsonApiErrorId with a GUID value
        return SomeMethodThatLogsTheError(error);
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions