Skip to content

Error instance serialization missing properties #110

Closed
@john-goldsmith

Description

@john-goldsmith

TL;DR: When deserializing an instance of Error, certain properties defined by the spec are dropped -- is this intentional and, if so, why?


The JSON:API spec states that error objects MAY have the following members:

id: a unique identifier for this particular occurrence of the problem.
links: a links object containing the following members:
    about: a link that leads to further details about this particular occurrence of the problem.
status: the HTTP status code applicable to this problem, expressed as a string value.
code: an application-specific error code, expressed as a string value.
title: a short, human-readable summary of the problem that SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization.
detail: a human-readable explanation specific to this occurrence of the problem. Like title, this field’s value can be localized.
source: an object containing references to the source of the error, optionally including any of the following members:
    pointer: a JSON Pointer [RFC6901] to the associated entity in the request document [e.g. "/data" for a primary data object, or "/data/attributes/title" for a specific attribute].
    parameter: a string indicating which URI query parameter caused the error.
meta: a meta object containing non-standard meta-information about the error.

However, when serializing an instance of Error, the id, links, links.about, source, source.pointer, source.parameter, and meta members are not supported:

if (err instanceof Error) {
const status = err.status || err.statusCode;
serializedError = {
status: status && status.toString(),
code: err.code,
title: err.title || err.constructor.name,
detail: err.message,
};

Current implementation:

const error = new Error('Something went wrong')
error.status = 500
error.code = 'abc123'
error.id = 'a745776d-08bc-486d-85ed-edc38dd120a0'
error.links = { about: 'https://examples.com' }
error.source = { pointer: '/data/attributes/title', parameter: 'include' }
error.meta = { time: Date.now() }
const serializedError = Serializer.serializeError(error)
/*
{
  errors: [
    {
      status: '500',
      code: 'abc123'
      title: 'Error'
      detail: 'Something went wrong'
    }
  ]
}
*/

If all of the JSON:API error object properties were supported, then custom errors could package up all of the related data and then be reused throughout an application while still maintaining Error class semantics. I realize that the serializeError function can also be passed an arbitrary object that gets validated, but this doesn't seem ideal.

Proposed usage:

// errors/my-custom-error.js
class MyCustomerError extends Error {
  constructor(message = 'Lorem ipsum dolor...') {
    super(message)
    this.status = 500
    this.code = 'abc123'
    this.title = 'MyCustomError'
    this.detail = message
    this.id = 'a745776d-08bc-486d-85ed-edc38dd120a0'
    this.links = { about: 'https://examples.com' }
    this.source = { pointer: '/data/attributes/title', parameter: 'include' }
    this.meta = { time: Date.now() }
  }
}

// somewhere/else.js
const serializedError = Serializer.serializeError(new MyCustomerError())

I'm happy to submit a PR if this is something you'd like to include. Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions