Custom error code ошибка

Create global or application-level Exception handlers and return Custom Error Messages in Spring REST APIs.

Overview

Effective communication is the key to healthy and efficient relationships. Interestingly, the same applies to any Client and Server relationships. The client’s request may succeed or fail on the server. However, the server should provide the most appropriate status code in either of the outcomes.

Although sending a correct status code is enough for a client to take real action based on the outcome of a request, in case of failures, the client may need more details about what went wrong. For example, failure details like the exception type and an error message can help clients log the error or provide appropriate failure messages to their clients.

This article will teach How to handle different failures and return Custom Error Messages from a Spring REST API. If you don’t know how to handle exceptions in Spring REST API, please read Spring Rest Service Exception Handling.

Return a Generic Error Message using @ResponseStatus

The most basic way of returning an error message from a REST API is to use the @ResponseStatus annotation. We can add the error message in the annotation’s reason field. Although we can only return a generic error message, we can specify exception-specific error messages.

Next is an example of a @ControllerAdvice using @ResponseStatus annotations to return exception-specific error messages.

@ControllerAdvice public class ApplicationExceptionHandler { @ResponseStatus( value = HttpStatus.NOT_FOUND, reason = "Requested Student Not Found") @ExceptionHandler(StudentNotFoundException.class) public void handleException(StudentNotFoundException e) { } @ResponseStatus( value = HttpStatus.BAD_REQUEST, reason = "Received Invalid Input Parameters") @ExceptionHandler(InputValidationException.class) public void handleException(InputValidationException e) { } @ResponseStatus( value = HttpStatus.GATEWAY_TIMEOUT, reason = "Upstream Service Not Responding, Try Again") @ExceptionHandler(ServiceUnavailableException.class) public void handleException(ServiceUnavailableException e) { } }

Code language: Java (java)

The Exception handler class has three exception handlers, each of which returns a specific HTTP Response Status. Each response status specifies a reason field with a particular error message.

To view the error message in the response, ensure you have turned on include-messages in the server configuration. To learn more about Spring Boot server configurations, please visit Spring Boot Embedded Tomcat Configuration.

server: error: include-message: always

Code language: YAML (yaml)

Next is an example of a response object the REST API returns. Note that the response object has the specified error message.

{ "timestamp": "", "status": 404, "error": "Not Found", "message": "Requested Student Not Found", "path": "/students/Jack" }

Code language: JSON / JSON with Comments (json)

Although we can specify exception-specific error messages, it is still not informative. Therefore in the following sections, we will learn how to return a more specific error message from Spring REST API.

Return Error Message Using Custom Error Object

Let’s create a class representing the error message and the status code. We will return an instance of that in case of errors.

Next is the Error class representing the status code and a String message. We use a few Lombok annotations that introduce regular getter and setter methods and a constructor using the final fields.

Custom Response Error Class

@Data @RequiredArgsConstructor public class Error { private final HttpStatus httpStatus; private final String message; }

Code language: Java (java)

Now that we have an error model created, we will use it to return a detailed error message from Controller Advice.

@ExceptionHandler(StudentNotFoundException.class) public ResponseEntity handleException( StudentNotFoundException e) { Error error = new Error(HttpStatus.NOT_FOUND, e.getLocalizedMessage()); return new ResponseEntity<>(error, error.getHttpStatus()); }

Code language: Java (java)

The exception handler returns an instance of the Error class populated with the exception message and HTTP Status Code.

Now, we can throw our Not Found Exception with a custom error message.

throw new StudentNotFoundException ("Student service failed, studentId : " + studentId);

Code language: Java (java)

When the REST API cannot find the requested resource, we get a detailed error as a response.

{ "httpStatus": "NOT_FOUND", "message": "Student service failed, studentId : Jack" }

Code language: JSON / JSON with Comments (json)

Return Error Message Using HashMap

Also, instead of creating a dedicated error class, we can return a detailed error message using a simple HashMap. Next is an example of producing and returning a Custom Error Message using Java HashMap.

@ExceptionHandler(StudentNotFoundException.class) public ResponseEntity<Map<String, String>> handleException(StudentNotFoundException e) { Map<String, String> errorResponse = Map.of( "message", e.getLocalizedMessage(), "status", HttpStatus.NOT_FOUND.toString() ); return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND); }

Code language: Java (java)

Handle Bad Request Exceptions

The Bad Request errors are the Client errors where the client’s request doesn’t meet the requirements of the target server. This section will see how to handle Bad Request exceptions and provide a custom or detailed error response.

Type Mismatch Exceptions

The Type Mismatch Exceptions occur when Spring Controller cannot map the request parameters, path variables, or header values into controller method arguments. This section covers the handling of MethodArgumentTypeMismatchException and TypeMismatchException.

Spring throws MethodArgumentTypeMismatchException when the controller argument doesn’t have a required type. On the other hand, Spring throws TypeMismatchException when there is a type mismatch while setting Bean properties. Also, both exceptions provide a detailed error message that we can use to prepare the Error object.

To demonstrate that, next is an example of Handling MethodArgumentTypeMismatchException and TypeMismatchException and returning a detailed error message in Controller Advice.

@ExceptionHandler({ MethodArgumentTypeMismatchException.class, TypeMismatchException.class }) public ResponseEntity<Map<String, String>> handleException(TypeMismatchException e) { Map<String, String> errorResponse = Map.of( "message", e.getLocalizedMessage(), "status", HttpStatus.BAD_REQUEST.toString() ); return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST); }

Code language: Java (java)

Note that the controller advice catches both exceptions; however, the method arguments accept an exception of type TypeMismatchException because it is the parent of the other exception.

Next, the snippet shows a detailed error message when we call a rest endpoint with an incompatible path variable leading to MethodArgumentTypeMismatchException.

{ "httpStatus": "BAD_REQUEST", "message": "Failed to convert value of type 'java.lang.String' to required type 'java.lang.Long'; nested exception is java.lang.NumberFormatException: For input String: "Jack"" }

Code language: JSON / JSON with Comments (json)

Bean Validation Exceptions

The Bean Validation exceptions occur when the request contents do not pass the provided validations.

The BindException occurs when the binding errors are fatal. While the MethodArgumentNotValidException occurs when validations specified by @Valid fail. Note that the MethodArgumentNotValidException is a subclass of BindException. Thus, we can handle them using the same Spring REST API’s exception handler.

@ExceptionHandler({ BindException.class, MethodArgumentNotValidException.class }) public ResponseEntity<Map<String, Object>> handleException(BindException e) { List<String> errors = new ArrayList<>(); e.getFieldErrors() .forEach(err -> errors.add(err.getField() + ": " + err.getDefaultMessage())); e.getGlobalErrors() .forEach(err -> errors.add(err.getObjectName() + ": " + err.getDefaultMessage())); Map<String, Object> errorResponse = Map.of( "error", errors, "message", e.getLocalizedMessage(), "status", HttpStatus.BAD_REQUEST.toString() ); return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST); }

Code language: Java (java)

Here we have created a List<String> to represent individual binding errors and add that to the response Map. Instead, we can add a List<String> field to the Error class we created in the previous section and populate the list with individual errors.

Spring throws HttpMediaTypeNotSupportedException, when a POST, PUT, or PATCH endpoint on the server cannot handle the content type sent by the client. The REST Controllers on the server specify the content type they can support. When the media type that a client sends doesn’t match, the client gets this exception back.

To demonstrate, next is an example of handling HttpMediaTypeNotSupportedException and returning a custom error response.

@ExceptionHandler(HttpMediaTypeNotSupportedException.class) public ResponseEntity<Map<String, String>> handleException( HttpMediaTypeNotSupportedException e) { String provided = e.getContentType().toString(); List<String> supported = e.getSupportedMediaTypes().stream() .map(MimeType::toString) .collect(Collectors.toList()); String error = provided + " is not one of the supported media types (" + String.join(", ", supported) + ")"; Map<String, String> errorResponse = Map.of( "error", error, "message", e.getLocalizedMessage(), "status", HttpStatus.UNSUPPORTED_MEDIA_TYPE.toString() ); return new ResponseEntity<>(errorResponse, HttpStatus.UNSUPPORTED_MEDIA_TYPE); }

Code language: Java (java)

As seen in the exception handler above, the instance of HttpMediaTypeNotSupportedException provides detailed information about the incorrect media type we provided and a list of actually supported media types. Thus, we create a custom error message based on the available information.

{ "error":"text/plain;charset=UTF-8 is not one of the supported media types ( application/octet-stream, text/plain, application/xml, text/xml, application/x-www-form-urlencoded, application/*+xml, multipart/form-data, multipart/mixed, application/json, application/*+json, */*)", "message":"Content type 'text/plain;charset=UTF-8' not supported", "status":"415 UNSUPPORTED_MEDIA_TYPE" }

Code language: JSON / JSON with Comments (json)

The above snippet shows a client’s sample error response when it sends a request with an invalid media type.

Handle Request Body Not Readable Exception

Now we will see an example of handling HttpMessageNotReadableException and returning a custom error response. The HttpMessageNotReadableException occurs when the request body is missing or unreadable.

@ExceptionHandler(HttpMessageNotReadableException.class) public ResponseEntity<Map<String, String>> handleException( HttpMessageNotReadableException e) throws IOException { Map<String, String> errorResponse = Map.of( "message", e.getLocalizedMessage(), "status", HttpStatus.BAD_REQUEST.toString() ); return new ResponseEntity<>(errorResponse, HttpStatus.BAD_REQUEST); }

Code language: Java (java)

Handle HTTP Request Method Not Supported Exception

The HttpMethodNotSupportedException occurs when the HTTP endpoint on the REST API does not support the HTTP request method. Let’s write an exception handler for HttpMethodNotSupportedException and return a detailed error message.

@ExceptionHandler(HttpRequestMethodNotSupportedException.class) public ResponseEntity<Map<String, String>> handleException( HttpRequestMethodNotSupportedException e) throws IOException { String provided = e.getMethod(); List<String> supported = List.of(e.getSupportedMethods()); String error = provided + " is not one of the supported Http Methods (" + String.join(", ", supported) + ")"; Map<String, String> errorResponse = Map.of( "error", error, "message", e.getLocalizedMessage(), "status", HttpStatus.METHOD_NOT_ALLOWED.toString() ); return new ResponseEntity<>(errorResponse, HttpStatus.METHOD_NOT_ALLOWED); }

Code language: Java (java)

As seen in the exception handler above, the exception instance provides detailed information about the provided HTTP Method and an array of Supported HTTP Methods. We use it to form a clear error message.

{ "error": "GET is not one of the supported Http Methods (POST)", "message": "Request method 'GET' not supported", "status": "405 METHOD_NOT_ALLOWED" }

Code language: JSON / JSON with Comments (json)

The snippet showed an example response when the client attempted to execute a GET endpoint, while the REST API supports only POST.

Default Exception Handler

Similarly, we can create a default exception handler advice that handles all Exception types. Spring attempts to find the most specific handler when we have multiple exception handlers and falls back to the default handler if there is no suitable handler.

@ExceptionHandler(Exception.class) public ResponseEntity<Map<String, String>> handleException( Exception e) throws IOException { Map<String, String> errorResponse = Map.of( "message", e.getLocalizedMessage(), "status", HttpStatus.INTERNAL_SERVER_ERROR.toString() ); return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR); }

Code language: Java (java)

Above is an example of writing a default exception handler that returns an error message by the exception instance and an HTTP Status of 500.

Summary

This detailed tutorial taught us how to Return Custom Error Messages in Spring REST API. Firstly, we understood that Spring returns a generic error message and the most suitable HTTP Status Code by default. However, we can write our exception handlers for specific exceptions using @ControllerAdvice and produce a custom and detailed error response.

For more on Spring and Spring Boot Tutorials, please visit Spring Tutorials.


A custom error code can also be associated with validation rules by calling the WithErrorCode method:

public class PersonValidator : AbstractValidator<Person> 
{
  public PersonValidator() 
  {
    RuleFor(person => person.Surname).NotNull().WithErrorCode("ERR1234");        
    RuleFor(person => person.Forename).NotNull();
  }
}

The resulting error code can be obtained from the ErrorCode property on the ValidationFailure:

var validator = new PersonValidator();
var result = validator.Validate(new Person());
foreach (var failure in result.Errors)
{
  Console.WriteLine($"Property: {failure.PropertyName} Error Code: {failure.ErrorCode}");
}

The output would be:

Property: Surname Error Code: ERR1234
Property: Forename Error Code: NotNullValidator

ErrorCode and Error Messages¶

The ErrorCode is also used to determine the default error message for a particular validator. At a high level:

  • The error code is used as the lookup key for an error message. For example, a NotNull() validator has a default error code of NotNullValidator, which used to look up the error messages from the LanguageManager. See the documentation on localization.
  • If you provide an error code, you could also provide a localized message with the name of that error code to create a custom message.
  • If you provide an error code but no custom message, the message will fall back to the default message for that validator. You’re not required to add a custom message.
  • Using ErrorCode can also be used to override the default error message. For example, if you use a custom Must() validator, but you’d like to reuse the NotNull() validator’s default error message, you can call WithErrorCode("NotNullValidator") to achieve this result.

Update your code to assign your prototype to the Error.prototype and the instanceof and your asserts work.

function NotImplementedError(message = "") {
    this.name = "NotImplementedError";
    this.message = message;
}
NotImplementedError.prototype = Error.prototype;

However, I would just throw your own object and just check the name property.

throw {name : "NotImplementedError", message : "too lazy to implement"}; 

Edit based on comments

After looking at the comments and trying to remember why I would assign prototype to Error.prototype instead of new Error() like Nicholas Zakas did in his article, I created a jsFiddle with the code below:

function NotImplementedError(message = "") {
  this.name = "NotImplementedError";
  this.message = message;
}
NotImplementedError.prototype = Error.prototype;

function NotImplementedError2(message = "") {
  this.message = message;
}
NotImplementedError2.prototype = new Error();

try {
  var e = new NotImplementedError("NotImplementedError message");
  throw e;
} catch (ex1) {
  console.log(ex1.stack);
  console.log("ex1 instanceof NotImplementedError = " + (ex1 instanceof NotImplementedError));
  console.log("ex1 instanceof Error = " + (ex1 instanceof Error));
  console.log("ex1.name = " + ex1.name);
  console.log("ex1.message = " + ex1.message);
}

try {
  var e = new NotImplementedError2("NotImplementedError2 message");
  throw e;
} catch (ex1) {
  console.log(ex1.stack);
  console.log("ex1 instanceof NotImplementedError2 = " + (ex1 instanceof NotImplementedError2));
  console.log("ex1 instanceof Error = " + (ex1 instanceof Error));
  console.log("ex1.name = " + ex1.name);
  console.log("ex1.message = " + ex1.message);
}

The console output was this.

undefined
ex1 instanceof NotImplementedError = true
ex1 instanceof Error = true
ex1.name = NotImplementedError
ex1.message = NotImplementedError message
Error
    at window.onload (http://fiddle.jshell.net/MwMEJ/show/:29:34)
ex1 instanceof NotImplementedError2 = true
ex1 instanceof Error = true
ex1.name = Error
ex1.message = NotImplementedError2 message

This confirmes the «problem» I ran into was the stack property of the error was the line number where new Error() was created, and not where the throw e occurred. However, that may be better that having the side effect of a NotImplementedError.prototype.name = "NotImplementedError" line affecting the Error object.

Also, notice with NotImplementedError2, when I don’t set the .name explicitly, it is equal to «Error». However, as mentioned in the comments, because that version sets prototype to new Error(), I could set NotImplementedError2.prototype.name = "NotImplementedError2" and be OK.

Abhay's user avatar

Abhay

3,1411 gold badge19 silver badges29 bronze badges

answered May 16, 2009 at 3:51

Kevin Hakanson's user avatar

Kevin HakansonKevin Hakanson

41.2k23 gold badges126 silver badges155 bronze badges

22

In ES2015, you can use class to do this cleanly:

class NotImplemented extends Error {
  constructor(message = "", ...args) {
    super(message, ...args);
    this.message = message + " has not yet been implemented.";
  }
}

This does not modify the global Error prototype, allows you to customize message, name, and other attributes, and properly captures the stack. It’s also pretty readable.

Of course, you may need to use a tool like babel if your code will be running on older browsers.

answered Jun 14, 2017 at 16:09

rattray's user avatar

rattrayrattray

5,0141 gold badge33 silver badges26 bronze badges

2

All of the above answers are terrible awful — really. Even the one with 107 ups! The real answer is here guys:

Inheriting from the Error object — where is the message property?

TL;DR:

A. The reason message isn’t being set is that Error is a function that returns a new Error object and does not manipulate this in any way.

B. The way to do this right is to return the result of the apply from the constructor, as well as setting the prototype in the usual complicated javascripty way:

function MyError() {
    var temp = Error.apply(this, arguments);
    temp.name = this.name = 'MyError';
    this.message = temp.message;
    if(Object.defineProperty) {
        // getter for more optimizy goodness
        /*this.stack = */Object.defineProperty(this, 'stack', { 
            get: function() {
                return temp.stack
            },
            configurable: true // so you can change it if you want
        })
    } else {
        this.stack = temp.stack
    }
}
//inherit prototype using ECMAScript 5 (IE 9+)
MyError.prototype = Object.create(Error.prototype, {
    constructor: {
        value: MyError,
        writable: true,
        configurable: true
    }
});

var myError = new MyError("message");
console.log("The message is: '" + myError.message + "'"); // The message is: 'message'
console.log(myError instanceof Error); // true
console.log(myError instanceof MyError); // true
console.log(myError.toString()); // MyError: message
console.log(myError.stack); // MyError: message n 
// <stack trace ...>


 
//for EMCAScript 4 or ealier (IE 8 or ealier), inherit prototype this way instead of above code:
/*
var IntermediateInheritor = function() {};
IntermediateInheritor.prototype = Error.prototype;
MyError.prototype = new IntermediateInheritor();
*/

You could probably do some trickery to enumerate through all the non-enumerable properties of the tmp Error to set them rather than explicitly setting only stack and message, but the trickery isn’t supported in ie<9

Community's user avatar

answered Jul 26, 2013 at 21:12

B T's user avatar

B TB T

56.7k34 gold badges186 silver badges207 bronze badges

4

If anyone is curious on how to create a custom error and get the stack trace:

function CustomError(message) {
  this.name = 'CustomError';
  this.message = message || '';
  var error = new Error(this.message);
  error.name = this.name;
  this.stack = error.stack;
}
CustomError.prototype = Object.create(Error.prototype);

try {
  throw new CustomError('foobar');
}
catch (e) {
  console.log('name:', e.name);
  console.log('message:', e.message);
  console.log('stack:', e.stack);
}

ThomasReggi's user avatar

ThomasReggi

54.4k85 gold badges236 silver badges419 bronze badges

answered Dec 22, 2014 at 2:12

risto's user avatar

ristoristo

1,2749 silver badges11 bronze badges

class NotImplementedError extends Error {
  constructor(message) {
    super(message);
    this.message = message;
  }
}
NotImplementedError.prototype.name = 'NotImplementedError';
module.exports = NotImplementedError;

and

try {
  var e = new NotImplementedError("NotImplementedError message");
  throw e;
} catch (ex1) {
  console.log(ex1.stack);
  console.log("ex1 instanceof NotImplementedError = " + (ex1 instanceof NotImplementedError));
  console.log("ex1 instanceof Error = " + (ex1 instanceof Error));
  console.log("ex1.name = " + ex1.name);
  console.log("ex1.message = " + ex1.message);
}

It is just a class representation of this answer.

output

NotImplementedError: NotImplementedError message
  ...stacktrace
ex1 instanceof NotImplementedError = true
ex1 instanceof Error = true
ex1.name = NotImplementedError
ex1.message = NotImplementedError message

answered Aug 10, 2020 at 8:57

gramcha's user avatar

gramchagramcha

6929 silver badges16 bronze badges

This section of the standard may explain why the Error.apply call doesn’t initialize the object:

15.11.1 The Error Constructor Called as a Function

When Error is called as a function rather than as a constructor, it creates and
initialises a new Error object. Thus the function call Error(…) is
equivalent to the object creation expression new Error(…) with the
same arguments.

In this case the Error function probably determines that it’s not being called as a constructor, so it returns a new Error instance rather than initializing the this object.

Testing with the following code seems to demonstrate that this is in fact what’s happening:

function NotImplementedError() { 
   var returned = Error.apply(this, arguments);
   console.log("returned.message = '" + returned.message + "'");
   console.log("this.message = '" + this.message + "'");
}
NotImplementedError.prototype = new Error();

var nie = new NotImplementedError("some message");

The following output is generated when this is run:

returned.message = 'some message'
this.message = ''

answered Aug 12, 2011 at 6:31

Dave's user avatar

DaveDave

4,4001 gold badge34 silver badges39 bronze badges

9

I like to do it like this:

  • Make use of name so toString() throws "{code}: {message}"
  • Return same thing to super so it appears the same in the stacktrace
  • Attach code to error.code as checking/parsing a code is better in code than checking a message, which you might want to localize for example
  • Attach message to error.message as an alternative to error.toString()
class AppException extends Error {
  constructor(code, message) {
    const fullMsg = message ? `${code}: ${message}` : code;
    super(fullMsg);
    this.name = code;
    this.code = code;
    this.message = fullMsg;
  }
  
  toString() {
    return this.message;
  }
}

// Just a code
try {
  throw new AppException('FORBIDDEN');
} catch(e) {
  console.error(e);
  console.error(e.toString());
  console.log(e.code === 'FORBIDDEN');
}

// A code and a message
try {
  throw new AppException('FORBIDDEN', 'You don't have access to this page');
} catch(e) {
  console.error(e);
  console.error(e.toString());
  console.log(e.code === 'FORBIDDEN');
}

answered Sep 21, 2018 at 23:42

Dominic's user avatar

DominicDominic

62k20 gold badges136 silver badges162 bronze badges

function InvalidValueError(value, type) {
    this.message = "Expected `" + type.name + "`: " + value;
    var error = new Error(this.message);
    this.stack = error.stack;
}
InvalidValueError.prototype = new Error();
InvalidValueError.prototype.name = InvalidValueError.name;
InvalidValueError.prototype.constructor = InvalidValueError;

answered Nov 20, 2013 at 5:43

Pierre Voisin's user avatar

1

Accoring to Joyent you shouldn’t mess with the stack property (which I see in lots of answers given here), because it will have a negative impact on performance. Here is what they say:

stack: generally, don’t mess with this. Don’t even augment it. V8 only computes it if someone actually reads the property, which improves performance dramatically for handlable errors. If you read the property just to augment it, you’ll end up paying the cost even if your caller doesn’t need the stack.

I like and would like to mention their idea of wrapping the original error which is a nice replacement for passing on the stack.

So here is how I create a custom error, considering the above mentioned:

es5 version:

function RError(options) {
    options = options || {}; // eslint-disable-line no-param-reassign
    this.name = options.name;
    this.message = options.message;
    this.cause = options.cause;

    // capture stack (this property is supposed to be treated as private)
    this._err = new Error();

    // create an iterable chain
    this.chain = this.cause ? [this].concat(this.cause.chain) : [this];
}
RError.prototype = Object.create(Error.prototype, {
    constructor: {
        value: RError,
        writable: true,
        configurable: true
    }
});

Object.defineProperty(RError.prototype, 'stack', {
    get: function stack() {
        return this.name + ': ' + this.message + 'n' + this._err.stack.split('n').slice(2).join('n');
    }
});

Object.defineProperty(RError.prototype, 'why', {
    get: function why() {
        var _why = this.name + ': ' + this.message;
        for (var i = 1; i < this.chain.length; i++) {
            var e = this.chain[i];
            _why += ' <- ' + e.name + ': ' + e.message;
        }
        return _why;
    }
});

// usage

function fail() {
    throw new RError({
        name: 'BAR',
        message: 'I messed up.'
    });
}

function failFurther() {
    try {
        fail();
    } catch (err) {
        throw new RError({
            name: 'FOO',
            message: 'Something went wrong.',
            cause: err
        });
    }
}

try {
    failFurther();
} catch (err) {
    console.error(err.why);
    console.error(err.stack);
    console.error(err.cause.stack);
}

es6 version:

class RError extends Error {
    constructor({name, message, cause}) {
        super();
        this.name = name;
        this.message = message;
        this.cause = cause;
    }
    [Symbol.iterator]() {
        let current = this;
        let done = false;
        const iterator = {
            next() {
                const val = current;
                if (done) {
                    return { value: val, done: true };
                }
                current = current.cause;
                if (!val.cause) {
                    done = true;
                }
                return { value: val, done: false };
            }
        };
        return iterator;
    }
    get why() {
        let _why = '';
        for (const e of this) {
            _why += `${_why.length ? ' <- ' : ''}${e.name}: ${e.message}`;
        }
        return _why;
    }
}

// usage

function fail() {
    throw new RError({
        name: 'BAR',
        message: 'I messed up.'
    });
}

function failFurther() {
    try {
        fail();
    } catch (err) {
        throw new RError({
            name: 'FOO',
            message: 'Something went wrong.',
            cause: err
        });
    }
}

try {
    failFurther();
} catch (err) {
    console.error(err.why);
    console.error(err.stack);
    console.error(err.cause.stack);
}

I’ve put my solution into a module, here it is: https://www.npmjs.com/package/rerror

answered Oct 19, 2016 at 9:48

borisdiakur's user avatar

borisdiakurborisdiakur

10.2k7 gold badges67 silver badges99 bronze badges

I had a similar issue to this. My error needs to be an instanceof both Error and NotImplemented, and it also needs to produce a coherent backtrace in the console.

My solution:

var NotImplemented = (function() {
  var NotImplemented, err;
  NotImplemented = (function() {
    function NotImplemented(message) {
      var err;
      err = new Error(message);
      err.name = "NotImplemented";
      this.message = err.message;
      if (err.stack) this.stack = err.stack;
    }
    return NotImplemented;
  })();
  err = new Error();
  err.name = "NotImplemented";
  NotImplemented.prototype = err;

  return NotImplemented;
}).call(this);

// TEST:
console.log("instanceof Error: " + (new NotImplemented() instanceof Error));
console.log("instanceof NotImplemented: " + (new NotImplemented() instanceofNotImplemented));
console.log("message: "+(new NotImplemented('I was too busy').message));
throw new NotImplemented("just didn't feel like it");

Result of running with node.js:

instanceof Error: true
instanceof NotImplemented: true
message: I was too busy

/private/tmp/t.js:24
throw new NotImplemented("just didn't feel like it");
      ^
NotImplemented: just didn't feel like it
    at Error.NotImplemented (/Users/colin/projects/gems/jax/t.js:6:13)
    at Object.<anonymous> (/Users/colin/projects/gems/jax/t.js:24:7)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:487:10)
    at process.startup.processNextTick.process._tickCallback (node.js:244:9)

The error passes all 3 of my criteria, and although the stack property is nonstandard, it is supported in most newer browsers which is acceptable in my case.

answered May 16, 2012 at 11:56

sinisterchipmunk's user avatar

0

I used the Constructor Pattern to create the new error object. I defined the prototype chain such as an Error instance. See the MDN Error constructor reference.

You can check this snippet on this gist.

IMPLEMENTATION

// Creates user-defined exceptions
var CustomError = (function() {
  'use strict';

  //constructor
  function CustomError() {
    //enforces 'new' instance
    if (!(this instanceof CustomError)) {
      return new CustomError(arguments);
    }
    var error,
      //handles the arguments object when is passed by enforcing a 'new' instance
      args = Array.apply(null, typeof arguments[0] === 'object' ? arguments[0] : arguments),
      message = args.shift() || 'An exception has occurred';

    //builds the message with multiple arguments
    if (~message.indexOf('}')) {
      args.forEach(function(arg, i) {
        message = message.replace(RegExp('\{' + i + '}', 'g'), arg);
      });
    }

    //gets the exception stack
    error = new Error(message);
    //access to CustomError.prototype.name
    error.name = this.name;

    //set the properties of the instance
    //in order to resemble an Error instance
    Object.defineProperties(this, {
      stack: {
        enumerable: false,
        get: function() { return error.stack; }
      },
      message: {
        enumerable: false,
        value: message
      }
    });
  }

  // Creates the prototype and prevents the direct reference to Error.prototype;
  // Not used new Error() here because an exception would be raised here,
  // but we need to raise the exception when CustomError instance is created.
  CustomError.prototype = Object.create(Error.prototype, {
    //fixes the link to the constructor (ES5)
    constructor: setDescriptor(CustomError),
    name: setDescriptor('JSU Error')
  });

  function setDescriptor(value) {
    return {
      configurable: false,
      enumerable: false,
      writable: false,
      value: value
    };
  }

  //returns the constructor
  return CustomError;
}());

USAGE

The CustomError constructor can receive many arguments to build the message, e.g.

var err1 = new CustomError("The url of file is required"),
    err2 = new CustomError("Invalid Date: {0}", +"date"),
    err3 = new CustomError("The length must be greater than {0}", 4),
    err4 = new CustomError("Properties .{0} and .{1} don't exist", "p1", "p2");

throw err4;

And this is how the custom error looks:

Custom error prototype chain

answered Feb 16, 2015 at 17:33

jherax's user avatar

jheraxjherax

5,2385 gold badges37 silver badges49 bronze badges

0

This is my implementation:

class HttpError extends Error {
  constructor(message, code = null, status = null, stack = null, name = null) {
    super();
    this.message = message;
    this.status = 500;

    this.name = name || this.constructor.name;
    this.code = code || `E_${this.name.toUpperCase()}`;
    this.stack = stack || null;
  }

  static fromObject(error) {
    if (error instanceof HttpError) {
      return error;
    }
    else {
      const { message, code, status, stack } = error;
      return new ServerError(message, code, status, stack, error.constructor.name);
    }
  }

  expose() {
    if (this instanceof ClientError) {
      return { ...this };
    }
    else {
      return {
        name: this.name,
        code: this.code,
        status: this.status,
      }
    }
  }
}

class ServerError extends HttpError {}

class ClientError extends HttpError { }

class IncorrectCredentials extends ClientError {
  constructor(...args) {
    super(...args);
    this.status = 400;
  }
}

class ResourceNotFound extends ClientError {
  constructor(...args) {
    super(...args);
    this.status = 404;
  }
}

Example usage #1:

app.use((req, res, next) => {
  try {
    invalidFunction();
  }
  catch (err) {
    const error = HttpError.fromObject(err);
    return res.status(error.status).send(error.expose());
  }
});

Example usage #2:

router.post('/api/auth', async (req, res) => {
  try {
    const isLogged = await User.logIn(req.body.username, req.body.password);

    if (!isLogged) {
      throw new IncorrectCredentials('Incorrect username or password');
    }
    else {
      return res.status(200).send({
        token,
      });
    }
  }
  catch (err) {
    const error = HttpError.fromObject(err);
    return res.status(error.status).send(error.expose());
  }
});

answered Sep 12, 2018 at 14:56

Rafal Enden's user avatar

Rafal EndenRafal Enden

3,0081 gold badge21 silver badges16 bronze badges

0

I just had to implement something like this and found that the stack was lost in my own error implementation. What I had to do was create a dummy error and retrieve the stack from that:

My.Error = function (message, innerException) {
    var err = new Error();
    this.stack = err.stack; // IMPORTANT!
    this.name = "Error";
    this.message = message;
    this.innerException = innerException;
}
My.Error.prototype = new Error();
My.Error.prototype.constructor = My.Error;
My.Error.prototype.toString = function (includeStackTrace) {
    var msg = this.message;
    var e = this.innerException;
    while (e) {
        msg += " The details are:n" + e.message;
        e = e.innerException;
    }
    if (includeStackTrace) {
        msg += "nnStack Trace:nn" + this.stack;
    }
    return msg;
}

answered May 31, 2012 at 11:14

Jules's user avatar

JulesJules

4,3193 gold badges43 silver badges72 bronze badges

1

This is implemented nicely in the Cesium DeveloperError:

  • Docs
  • Source

In it’s simplified form:

var NotImplementedError = function(message) {
    this.name = 'NotImplementedError';
    this.message = message;
    this.stack = (new Error()).stack;
}

// Later on...

throw new NotImplementedError();

answered Jan 27, 2014 at 1:34

Aram Kocharyan's user avatar

Aram KocharyanAram Kocharyan

20.1k11 gold badges81 silver badges96 bronze badges

2

The constructor needs to be like a factory method and return what you want. If you need additional methods/properties, you can add them to the object before returning it.

function NotImplementedError(message) { return new Error("Not implemented", message); }

x = new NotImplementedError();

Though I’m not sure why you’d need to do this. Why not just use new Error... ? Custom exceptions don’t really add much in JavaScript (or probably any untyped language).

answered Apr 23, 2009 at 22:42

pluckyglen's user avatar

pluckyglenpluckyglen

8197 silver badges9 bronze badges

1

At the expense of not being able to use instanceof, the following preserves the original stack trace and doesn’t use any non-standard tricks.

// the function itself
var fixError = function(err, name) {
    err.name = name;
    return err;
}

// using the function
try {
    throw fixError(new Error('custom error message'), 'CustomError');
} catch (e) {
    if (e.name == 'CustomError')
        console.log('Wee! Custom Error! Msg:', e.message);
    else
        throw e; // unhandled. let it propagate upwards the call stack
}

answered Apr 28, 2013 at 14:58

Gima's user avatar

GimaGima

1,89219 silver badges23 bronze badges

3

Another alternative , might not work in all enviroments.Atleast assured it works in nodejs 0.8
This approach uses a non standard way of modifying the internal proto prop

function myError(msg){ 
      var e = new Error(msg); 
      _this = this; 
      _this.__proto__.__proto__ = e;
}

kleopatra's user avatar

kleopatra

50.9k28 gold badges99 silver badges211 bronze badges

answered Jul 30, 2013 at 9:00

Chandu's user avatar

ChanduChandu

4,5812 gold badges17 silver badges13 bronze badges

If you are using Node/Chrome. The following snippet will get you extension which meets the following requirements.

  • err instanceof Error
  • err instanceof CustomErrorType
  • console.log() returns [CustomErrorType] when created with a message
  • console.log() returns [CustomErrorType: message] when created without a message
  • throw/stack provides the information at the point the error was created.
  • Works optimally in Node.JS, and Chrome.
  • Will pass instanceof checks in Chrome, Safari, Firefox and IE 8+, but will not have a valid stack outside of Chrome/Safari. I’m OK with that because I can debug in chrome, but code which requires specific error types will still function cross browser. If you need Node only you can easily remove the if statements and you’re good to go.

Snippet

var CustomErrorType = function(message) {
    if (Object.defineProperty) {
        Object.defineProperty(this, "message", {
            value : message || "",
            enumerable : false
        });
    } else {
        this.message = message;
    }

    if (Error.captureStackTrace) {
        Error.captureStackTrace(this, CustomErrorType);
    }
}

CustomErrorType.prototype = new Error();
CustomErrorType.prototype.name = "CustomErrorType";

Usage

var err = new CustomErrorType("foo");

Output

var err = new CustomErrorType("foo");
console.log(err);
console.log(err.stack);

[CustomErrorType: foo]
CustomErrorType: foo
    at Object.<anonymous> (/errorTest.js:27:12)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:906:3

/errorTest.js:30
        throw err;
              ^
CustomErrorType: foo
    at Object.<anonymous> (/errorTest.js:27:12)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:906:3

answered Oct 24, 2014 at 20:31

Owen Allen's user avatar

Owen AllenOwen Allen

11.2k9 gold badges50 silver badges63 bronze badges

The following worked for me taken from the official Mozilla documentation Error.

function NotImplementedError(message) {
    var instance = new Error(message);
    instance.name = 'NotImplementedError';

    Object.setPrototypeOf(instance, Object.getPrototypeOf(this));
    if (Error.captureStackTrace) {
        Error.captureStackTrace(instance, NotImplementedError);
    }
    return instance;
}

NotImplementedError.prototype = Object.create(Error.prototype, {
    constructor: {
        value: Error,
        enumerable: false,
        writable: true,
        configurable: true
    }
});

answered Jan 6, 2020 at 15:21

Zhunio's user avatar

0

Here is my solution for supporting pre-es2015 browsers. It does not do any fancy prototype tweaking and will not break debuggers.

/**  Custom Errors
    // Depends on underscore js
    // This will declare an CustError() class in both 'this' and '_exports' namespaces
    // ctor is optional
    declare_cust_error(function CustError(){}, {ns: [this, _exports], ctor: 
        function cust_err_ctor(instance, clazz, name, msg, info){
            q$.called(arguments)
        }
    })

    // Usage:
    // Second param (pojso) is optional
    try {
        throw CustError.create("foo", {k1: 'v1', k2: 'v2'})
    }catch(ex){
        if(CustError.is_inst(ex)){
            console.error("its a CustError", ex)
        } else {
            throw ex
        }
    }

**/
function declare_cust_error(error_class, opts){
    var p, c, cp
    if(!error_class||!(p=error_class.prototype))throw new Error("error_class must be a Class")
    try{
        c = p.constructor; cp = c.toString()
    }catch(ex){}
    if(!cp || cp.indexOf('function ') != 0 || cp.indexOf('[native code]') > 0)
        throw new Error("error_class must be a classic proto class (pre-es6) but got: " + error_class.toString())

    opts=opts||{}
    
    error_class.__is_cust_error__ = true
    error_class.__cust_error_name__ = c.name

    error_class.create = function cust_error_create(msg, info){
        var instance = new Error(msg)
        instance.info = info
        instance.__is_cust_error__ = true
        instance.__cust_error_name__ = c.name
        if(_.isFunction(opts.ctor)){
            opts.ctor(instance, error_class, c.name, msg, info)
        }
        return instance
    }

    error_class.is_inst = function cust_error_is_inst(instanace){
        return ( (instanace instanceof Error) && instanace.__cust_error_name__ === error_class.__cust_error_name__ )
    }
    
    // Declare error in namespace(s)
    _.each(_.isArray(opts.ns)?opts.ns:[opts.ns], function(ns){ ns[c.name] = error_class })

    return error_class

}

answered Oct 24, 2022 at 16:55

Timothy C. Quinn's user avatar

Timothy C. QuinnTimothy C. Quinn

3,6091 gold badge35 silver badges46 bronze badges

A lot of the methods above won’t work.

Errors

The last one is an actual error. If you use a string, it looks good, but it doesn’t give a stack trace. If you throw with Error, you can’t have "Uncaught BadError: bad", so you’ll have to remove the custom error (sadly). If you throw an object, it looks kind of off, and the final one is just an average error.

This method creates an error with a custom name while preserving stack tracing:

var errProto = Object.create(Error.prototype, {
  constructor: {
    value: Error,
    enumerable: false,
    writable: true,
    configurable: true
  }
})
var isFirefox = !!window.InstallTrigger
// Hide stack for Firefox only, as stacks can cause problems with high "frame" counts.
function createError(name, message, hideStack) {
  if (message == null) {
    message = ""
  }
  var customError = Error(message)
  customError.name = name
  Object.setPrototypeOf(customError, errProto)
  if (isFirefox && hideStack) {
    customError.stack = ""
  } else if (isFirefox) {
    var stack = customError.stack
    var newline = stack.indexOf("n") + 1
    stack = stack.slice(newline)
    customError.stack = stack
    var split = stack.split(":")
    if (split.length > 4) {
      var a = split[3]
      var b = split[4]
      var t = b.slice(0, b.indexOf("n"))
      customError.lineNumber = Number(a)
      customError.columnNumber = Number(t)
    }
  } else {
    var stack = customError.stack
    var split = stack.split("n")
    var secondPart = split.slice(2).join("n")
    stack = split[0] + "n" + secondPart
    customError.stack = stack
    var split = secondPart.split(":")
    var a = split[2]
    var b = split[3]
  }
  throw customError
}

var frame = 0

function aFunction() {
  if (++frame === 100) {
    createError("LazyError", "function getting lazy", false, true)
  } else {
    requestAnimationFrame(aFunction)
  }
}

setTimeout(aFunction, Math.random() * 500)
* {
  font-family: Verdana;
}
Check your inspector!

answered Dec 17, 2022 at 17:15

Infigon's user avatar

InfigonInfigon

5145 silver badges17 bronze badges

Try a new prototype object for each instance of the user defined error type. It allows instanceof checks to behave as usual plus type and message are correctly reported in Firefox and V8 (Chome, nodejs).

function NotImplementedError(message){
    if(NotImplementedError.innercall===undefined){
        NotImplementedError.innercall = true;
        NotImplementedError.prototype = new Error(message);
        NotImplementedError.prototype.name = "NotImplementedError";
        NotImplementedError.prototype.constructor = NotImplementedError;

        return new NotImplementedError(message);
    }
    delete NotImplementedError.innercall;
}

Note that an additional entry will preceed the otherwise correct stack.

answered Aug 19, 2012 at 21:09

Augustus Kling's user avatar

Augustus KlingAugustus Kling

3,2931 gold badge22 silver badges25 bronze badges

1

This is fastest way to do it:

    let thisVar = false

    if (thisVar === false) {
            throw new Error("thisVar is false. It should be true.")
    }

answered Feb 5, 2020 at 17:19

jlhs's user avatar

jlhsjlhs

1037 bronze badges

easier way. You could make your object inherit from the Error object.
Example:

function NotImplementError(message)
{
    this.message = message;
    Error.call();
    Error.call(message);
} 

what we are doing is using the function call() which call the constructor of the Error class so is basicly the same thing as implementing a class inheritance in other object oriented languages.

answered Mar 6, 2013 at 19:27

Paulo Enmanuel's user avatar

0

MDN has an excellent example:

try {
  throw new Error('Whoops!');
} catch (e) {
  console.log(e.name + ': ' + e.message);
}

answered Sep 4, 2017 at 21:59

Ronnie Royston's user avatar

Ronnie RoystonRonnie Royston

16.4k6 gold badges75 silver badges90 bronze badges

Sunday, 12 September 2021

Creating custom errors in JavaScript can be very useful. If you want to handle those errors in a catch block you can use the instanceof operator to check for that specific error. And with TypeScript, you can then safely use the fields and methods on your custom error.

Another benefit of custom errors is that you can provide your own constructor which lets you pass more information to the error. Which is information you can use in an error handler.

Custom JavaScript errors are almost as simple as creating an Error subclass, but there are two things you can do to make them even more useful.

Set the name

The first thing to enhance custom errors is to set this.name inside the constructor. This means your error name will appear in stack traces rather than the generic Error:.

Re-capture the stack trace

An unfortunate side-effect of creating a custom error is that your custom constructor will appear in the stack trace. This is because your super call is technically creating the error and the JavaScript VM records that in the generated stack trace. This isn’t useful and makes stack traces messier.

Removing this makes it easier to get to the code that’s thrown the error. You can do this with the Error.captureStackTrace static method.

An example

To demonstrate this, let’s create a custom error that captures extra information for a http API, so we can throw a desired http status and an error identifier.

class ApiError extends Error {
constructor(status, apiCode) {
super(`There was an error with your API request: "${apiCode}"`)
this.name = 'ApiError'
this.status = status
this.apiCode = apiCode
Error.captureStackTrace(this, ApiError)
}
}

That’s all you need, you could use it like this:

throw new ApiError(404, 'notFound')

// or

throw new ApiError(400, 'login.emailNotProvided')

and this will produce a stack trace like this:

/◦◦◦/custom-errors/main.js:4
  throw new ApiError(404, "notFound");
  ^

ApiError: There was an error with your API request: "notFound"
    at runApp (/◦◦◦/custom-errors/main.js:4:9)
    at main (/◦◦◦/custom-errors/main.js:12:3)
    at Object.<anonymous> (/◦◦◦/custom-errors/main.js:15:1)
    ◦◦◦ {
  status: 404,
  apiCode: 'notFound'
}

See examples/custom-errors for the exact source code.

The output shows that it has namespaced the error with ApiError: which is from us setting this.name.
The first line of the stack trace is not ApiError‘s constructor but runApp which was the method which threw the error.
Because of this, it now shows you the exact line of code that threw the error in the excerpt.

You can also see that status and apiCode have been stored on the error.

Catching errors

To complete this post, here’s an example of catching an ApiError and using the extra fields.

const express = require('express')
const app = express()

// From above
class ApiError extends Error {
/* ... */
}

// A route which results in an error
app.get('/', (req, res, next) => {
next(new ApiError(404, 'notFound'))
})

// An Express error handler, more info at:
// http://expressjs.com/en/guide/error-handling.html
app.use((error, req, res, next) => {
console.error('Handled error', error)

if (error instanceof ApiError) {
res.status(error.status).send({ apiCode: error.apiCode })
} else {
res.status(500).send({ apiCode: 'unknownError' })
}
})

app.listen(3000)

This shows throwing an ApiError in an ExpressJs context and handling it with an error middleware.
It checks for an ApiError with the instanceof operator, and then safely uses the fields on it to generate a http response.
The logic also nicely allows a generic http 500 error to be sent when unknown errors are thrown.

Bonus: static methods

When using custom errors another pattern I’ve used is to add static methods to easily create common errors. The does bring back the stack trace issue, so another Error.captureStackTrace is needed.

To demonstrate this, lets add some common errors to ApiError:

class ApiError extends Error {
static notFound() {
return new ApiError(404, 'general.notFound').trimStack()
}
static unauthorized() {
return new ApiError(401, 'general.unauthorized').trimStack()
}

// Same as above
constructor(/* ... */) {
/* ... */
}

trimStack() {
Error.captureStackTrace(this, ApiError)
return this
}
}

I found the utility function trimStack helps keeps these static methods easier to read and understand.

Now you can quickly create common errors with throw ApiError.notFound(), which is easier to read and hopefully leads to less mistakes. For the full source code see See examples/custom-errors.

Handling errors plays a major role in your application. In error situations, you want to know the details of the issue and how to solve it. When developing your app, you can create your own errors.

Errors in Node.js are extensible classes. This tutorial walks you through the creation of your own error class.

Node.js Series Overview

  • Node.js
  • Strings
  • Streams
  • Date & Time
  • Arrays
  • Promises
  • JSON
  • Iterators
  • Classes
  • Numbers
  • Objects
  • File System
  • Map
  • Process
  • Symbols
  • Platform/OS
  • HTTPS
  • Hashing
  1. Increase the Memory Limit for Your Process

  2. Why You Should Add “node” in Your Travis Config

  3. Create a PDF from HTML with Puppeteer and Handlebars

  4. Create Your Own Custom Error

  5. Retrieve a Request’s IP Address in Node.js

  6. Detect the Node.js Version in a Running Process or App

  7. How to Base64 Encode/Decode a Value in Node.js

  8. Check if a Value Is Null or Undefined in JavaScript or Node.js

  9. How to Fix “Uncaught SyntaxError: Cannot use import statement outside a module”

  10. Fix „Socket Hang Up“ Errors

  11. Nested Destructuring in JavaScript or Node.js


  1. Increase the Memory Limit for Your Process


  2. Why You Should Add “node” in Your Travis Config

  3. Create a PDF from HTML with Puppeteer and Handlebars

  4. Create Your Own Custom Error
  5. Retrieve a Request’s IP Address in Node.js

  6. Detect the Node.js Version in a Running Process or App

  7. How to Base64 Encode/Decode a Value in Node.js

  8. Check if a Value Is Null or Undefined in JavaScript or Node.js

  9. How to Fix “Uncaught SyntaxError: Cannot use import statement outside a module”

  10. Fix „Socket Hang Up“ Errors

  11. Nested Destructuring in JavaScript or Node.js

  1. String Replace All Appearances

  2. Remove All Whitespace From a String in JavaScript

  3. Generate a Random ID or String in Node.js or JavaScript

  4. Remove Extra Spaces From a String in JavaScript or Node.js

  5. Remove Numbers From a String in JavaScript or Node.js

  6. Get the Part Before a Character in a String in JavaScript or Node.js

  7. Get the Part After a Character in a String in JavaScript or Node.js

  8. How to Check if a Value is a String in JavaScript or Node.js

  9. Check If a String Includes All Strings in JavaScript/Node.js/TypeScript

  10. Check if a Value is a String in JavaScript and Node.js

  11. Limit and Truncate a String to a Given Length in JavaScript and Node.js

  12. Split a String into a List of Characters in JavaScript and Node.js

  13. How to Generage a UUID in Node.js

  14. Reverse a String in JavaScript or Node.js

  15. Split a String into a List of Lines in JavaScript or Node.js

  16. Split a String into a List of Words in JavaScript or Node.js

  17. Detect if a String is in camelCase Format in Javascript or Node.js

  18. Check If a String Is in Lowercase in JavaScript or Node.js

  19. Check If a String is in Uppercase in JavaScript or Node.js

  20. Get the Part After First Occurrence in a String in JavaScript or Node.js

  21. Get the Part Before First Occurrence in a String in JavaScript or Node.js

  22. Get the Part Before Last Occurrence in a String in JavaScript or Node.js

  23. Get the Part After Last Occurrence in a String in JavaScript or Node.js

  24. How to Count Words in a File

  25. How to Shuffle the Characters of a String in JavaScript or Node.js

  26. Append Characters or Words to a String in JavaScript or Node.js

  27. Check if a String is Empty in JavaScript or Node.js

  28. Ensure a String Ends with a Given Character in JavaScript or Node.js

  29. Left-Trim Characters Off a String in JavaScript or Node.js

  30. Right-Trim Characters Off a String in JavaScript or Node.js

  31. Lowercase the First Character of a String in JavaScript or Node.js

  32. Uppercase the First Character of a String in JavaScript or Node.js

  33. Prepend Characters or Words to a String in JavaScript or Node.js

  34. Check if a String is a Number

  35. Convert a String to Buffer


    (Coming soon)

  1. String Replace All Appearances

  2. Remove All Whitespace From a String in JavaScript

  3. Generate a Random ID or String in Node.js or JavaScript

  4. Remove Extra Spaces From a String in JavaScript or Node.js

  5. Remove Numbers From a String in JavaScript or Node.js

  6. Get the Part Before a Character in a String in JavaScript or Node.js

  7. Get the Part After a Character in a String in JavaScript or Node.js

  8. How to Check if a Value is a String in JavaScript or Node.js

  9. Check If a String Includes All Strings in JavaScript/Node.js/TypeScript

  10. Check if a Value is a String in JavaScript and Node.js

  11. Limit and Truncate a String to a Given Length in JavaScript and Node.js

  12. Split a String into a List of Characters in JavaScript and Node.js

  13. How to Generage a UUID in Node.js

  14. Reverse a String in JavaScript or Node.js

  15. Split a String into a List of Lines in JavaScript or Node.js

  16. Split a String into a List of Words in JavaScript or Node.js

  17. Detect if a String is in camelCase Format in Javascript or Node.js

  18. Check If a String Is in Lowercase in JavaScript or Node.js

  19. Check If a String is in Uppercase in JavaScript or Node.js

  20. Get the Part After First Occurrence in a String in JavaScript or Node.js

  21. Get the Part Before First Occurrence in a String in JavaScript or Node.js

  22. Get the Part Before Last Occurrence in a String in JavaScript or Node.js

  23. Get the Part After Last Occurrence in a String in JavaScript or Node.js

  24. How to Count Words in a File

  25. How to Shuffle the Characters of a String in JavaScript or Node.js

  26. Append Characters or Words to a String in JavaScript or Node.js

  27. Check if a String is Empty in JavaScript or Node.js

  28. Ensure a String Ends with a Given Character in JavaScript or Node.js

  29. Left-Trim Characters Off a String in JavaScript or Node.js

  30. Right-Trim Characters Off a String in JavaScript or Node.js

  31. Lowercase the First Character of a String in JavaScript or Node.js

  32. Uppercase the First Character of a String in JavaScript or Node.js

  33. Prepend Characters or Words to a String in JavaScript or Node.js

  34. Check if a String is a Number

  35. Convert a String to Buffer

    (Coming soon)

  1. Filter Data in Streams

  1. Get Number of Seconds Since Epoch in JavaScript

  2. Get Tomorrow’s Date in JavaScript

  3. Increase a Date in JavaScript by One Week

  4. Add Seconds to a Date in Node.js and JavaScript

  5. Add Month(s) to a Date in JavaScript or Node.js

  6. Add Week(s) to a Date in JavaScript or Node.js

  7. Get the Current Year in JavaScript or Node.js

  8. How to Get a UNIX Timestamp in JavaScript or Node.js

  9. How to Convert a UNIX Timestamp to a Date in JavaScript or Node.js

  10. Add Days to a Date in JavaScript or Node.js

  11. Get Yesterday’s Date in JavaScript or Node.js

  12. Add Minutes to a Date in JavaScript or Node.js

  13. Add Hours to a Date in JavaScript or Node.js

  14. Check If a Date Is Today in JavaScript or Node.js

  15. Check If a Date is Tomorrow in JavaScript or Node.js

  16. Check If a Date is Yesterday in JavaScript or Node.js

  17. How to Format a Date YYYY-MM-DD in JavaScript or Node.js

  1. Get Number of Seconds Since Epoch in JavaScript

  2. Get Tomorrow’s Date in JavaScript

  3. Increase a Date in JavaScript by One Week

  4. Add Seconds to a Date in Node.js and JavaScript

  5. Add Month(s) to a Date in JavaScript or Node.js

  6. Add Week(s) to a Date in JavaScript or Node.js

  7. Get the Current Year in JavaScript or Node.js

  8. How to Get a UNIX Timestamp in JavaScript or Node.js

  9. How to Convert a UNIX Timestamp to a Date in JavaScript or Node.js

  10. Add Days to a Date in JavaScript or Node.js

  11. Get Yesterday’s Date in JavaScript or Node.js

  12. Add Minutes to a Date in JavaScript or Node.js

  13. Add Hours to a Date in JavaScript or Node.js

  14. Check If a Date Is Today in JavaScript or Node.js

  15. Check If a Date is Tomorrow in JavaScript or Node.js

  16. Check If a Date is Yesterday in JavaScript or Node.js

  17. How to Format a Date YYYY-MM-DD in JavaScript or Node.js

  1. How to Run an Asynchronous Function in Array.map()

  2. How to Reset and Empty an Array

  3. Clone/Copy an Array in JavaScript and Node.js

  4. Get an Array With Unique Values (Delete Duplicates)

  5. Sort an Array of Integers in JavaScript and Node.js

  6. Sort a Boolean Array in JavaScript, TypeScript, or Node.js

  7. Check If an Array Contains a Given Value in JavaScript or Node.js

  8. Add an Item to the Beginning of an Array in JavaScript or Node.js

  9. Append an Item at the End of an Array in JavaScript or Node.js

  10. How to Exit and Stop a for Loop in JavaScript and Node.js

  11. Split an Array Into Smaller Array Chunks in JavaScript and Node.js

  12. How to Get an Index in a for…of Loop in JavaScript and Node.js

  13. How to Exit, Stop, or Break an Array#forEach Loop in JavaScript or Node.js

  14. Retrieve a Random Item From an Array in JavaScript or Node.js

  15. How to Reverse an Array in JavaScript and Node.js

  16. Sort an Array of Strings in JavaScript, TypeScript or Node.js

  17. Sort an Array of Objects in JavaScript, TypeScript or Node.js

  18. Check If a Value Is an Array in JavaScript or Node.js

  19. Join an Array of Strings to a Single String Value


  1. How to Run an Asynchronous Function in Array.map()

  2. How to Reset and Empty an Array

  3. for…of vs. for…in Loops

  4. Clone/Copy an Array in JavaScript and Node.js

  5. Get an Array With Unique Values (Delete Duplicates)

  6. Sort an Array of Integers in JavaScript and Node.js

  7. Sort a Boolean Array in JavaScript, TypeScript, or Node.js

  8. Check If an Array Contains a Given Value in JavaScript or Node.js

  9. Add an Item to the Beginning of an Array in JavaScript or Node.js

  10. Append an Item at the End of an Array in JavaScript or Node.js

  11. How to Exit and Stop a for Loop in JavaScript and Node.js

  12. Split an Array Into Smaller Array Chunks in JavaScript and Node.js

  13. How to Get an Index in a for…of Loop in JavaScript and Node.js

  14. How to Exit, Stop, or Break an Array#forEach Loop in JavaScript or Node.js

  15. Retrieve a Random Item From an Array in JavaScript or Node.js

  16. How to Reverse an Array in JavaScript and Node.js

  17. Sort an Array of Strings in JavaScript, TypeScript or Node.js

  18. Sort an Array of Objects in JavaScript, TypeScript or Node.js

  19. Check If a Value Is an Array in JavaScript or Node.js

  20. Join an Array of Strings to a Single String Value

  1. Callback and Promise Support in your Node.js Modules

  2. Run Async Functions/Promises in Sequence

  3. Run Async Functions/Promises in Parallel

  4. Run Async Functions in Batches

  5. How to Fix “Promise resolver undefined is not a function” in Node.js or JavaScript

  6. Detect if Value Is a Promise in Node.js and JavaScript

  7. Overview of Promise-Based APIs in Node.js


  1. Callback and Promise Support in your Node.js Modules

  2. Run Async Functions/Promises in Sequence

  3. Run Async Functions/Promises in Parallel

  4. Run Async Functions in Batches

  5. How to Fix “Promise resolver undefined is not a function” in Node.js or JavaScript

  6. Detect if Value Is a Promise in Node.js and JavaScript

  7. Overview of Promise-Based APIs in Node.js

  1. Human-Readable JSON.stringify() With Spaces and Line Breaks

  2. Write a JSON Object to a File

  3. Create a Custom “toJSON” Function in Node.js and JavaScript

  1. Human-Readable JSON.stringify() With Spaces and Line Breaks

  2. Write a JSON Object to a File

  3. Create a Custom “toJSON” Function in Node.js and JavaScript

  4. Securely Parse JSON

  1. Check If a Value Is Iterable in JavaScript or Node.js

  1. Check If a Value Is Iterable in JavaScript or Node.js

  1. Extend Multiple Classes (Multi Inheritance)

  2. Retrieve the Class Name at Runtime in JavaScript and Node.js

  1. Extend Multiple Classes (Multi Inheritance)

  2. Retrieve the Class Name at Runtime in JavaScript and Node.js

  1. Generate a Random Number in Range With JavaScript/Node.js

  2. Ensure a Positive Number in JavaScript or Node.js

  3. Check if a Number Is Infinity

  4. Check If a Number has Decimal Places in JavaScript or Node.js

  5. Use Numeric Separators for Better Readability

  1. Generate a Random Number in Range With JavaScript/Node.js

  2. Ensure a Positive Number in JavaScript or Node.js

  3. Check if a Number Is Infinity

  4. Check If a Number has Decimal Places in JavaScript or Node.js

  5. Use Numeric Separators for Better Readability

  1. How to Check if an Object is Empty in JavaScript or Node.js

  2. How to CamelCase Keys of an Object in JavaScript or Node.js

  3. How to Snake_Case Keys of an Object in JavaScript or Node.js

  4. How to Destructure a Dynamic Key in JavaScript or Node.js

  5. How to Get All Keys (Including Symbols) from an Object in JavaScript or Node.js

  6. How to Delete a Key From an Object in JavaScript or Node.js

  7. Iterate Through an Object’s Keys and Values in JavaScript or Node.js

  8. How to Convert URLSearchParams to Object

  9. Check If a Value Is an Object in JavaScript or Node.js

  10. Conditionally Add Properties to an Object in JavaScript or Node.js

  11. How to Lowercase Keys of an Object in JavaScript or Node.js

  1. How to Merge Objects

  2. How to Check if an Object is Empty in JavaScript or Node.js

  3. How to CamelCase Keys of an Object in JavaScript or Node.js

  4. How to Snake_Case Keys of an Object in JavaScript or Node.js

  5. How to Destructure a Dynamic Key in JavaScript or Node.js

  6. How to Get All Keys (Including Symbols) from an Object in JavaScript or Node.js

  7. How to Delete a Key From an Object in JavaScript or Node.js

  8. Iterate Through an Object’s Keys and Values in JavaScript or Node.js

  9. How to Convert URLSearchParams to Object

  10. Check If a Value Is an Object in JavaScript or Node.js

  11. Conditionally Add Properties to an Object in JavaScript or Node.js

  12. How to Lowercase Keys of an Object in JavaScript or Node.js

  1. Get a File’s Created Date

  2. Get a File’s Last Modified or Updated Date of a File

  3. How to Create an Empty File

  4. Check If a Path or File Exists

  5. Check If a Path Is a Directory

  6. Check If a Path Is a File

  7. Retrieve the Path to the User’s Home Directory

  8. Read File Content as String

  9. Check If a Directory Is Empty

  10. How to Create a Directory (and Parents If Needed)

  11. Get a File Name (With or Without Extension)

  1. Get a File’s Created Date

  2. Get a File’s Last Modified or Updated Date of a File

  3. How to Create an Empty File

  4. Check If a Path or File Exists

  5. How to Rename a File

  6. Check If a Path Is a Directory

  7. Check If a Path Is a File

  8. Retrieve the Path to the User’s Home Directory

  9. How to Touch a File

  10. Read File Content as String

  11. Check If a Directory Is Empty

  12. How to Create a Directory (and Parents If Needed)

  13. Get a File‘s Extension

  14. Get the Size of a File

  15. Get a File Name (With or Without Extension)

  16. Read a JSON File

  1. Create From Object

  2. Transform to an Object

  1. Determine the Node.js Version Running Your Script

  1. Determine the Node.js Version Running Your Script

  1. Check if a Value is a Symbol in JavaScript or Node.js

  1. Check if a Value is a Symbol in JavaScript or Node.js

  1. Detect if Running on Linux

  2. Detect if Running on macOS

  3. Detect if Running on Windows

  4. Check if Running on 64bit or 32bit Platform

  5. Constant for Platform-Specific Newline

  1. Detect if Running on Linux

  2. Detect if Running on macOS

  3. Detect if Running on Windows

  4. Check if Running on 64bit or 32bit Platform

  5. Constant for Platform-Specific Newline

  1. How to Download a File

  1. Retrieve the List of Supported Hash Algorithms

  1. Calculate an MD5 Hash

  2. Retrieve the List of Supported Hash Algorithms

  3. Calculate a SHA256 Hash

Create an Error Class

Node.js comes with an Error class. This error class gives you the core functionality of errors, like capturing a stack trace and assigning context data.

You can extend Node’s error class to create your own errors. Here’s an example of a NotEnoughCoffee error:

not-enough-coffee-error.js

class NotEnoughCoffee extends Error {  
  constructor (message) {
    super(message)

    // assign the error class name in your custom error (as a shortcut)
    this.name = this.constructor.name

    // capturing the stack trace keeps the reference to your error class
    Error.captureStackTrace(this, this.constructor);

    // you may also assign additional properties to your error
    this.isSleepy = true
  }
}

module.exports = NotEnoughCoffee  

The custom error extends the default Node.js error class. Setting the this.name property to the constructor’s name will reference NotEnoughCoffee in stack traces instead of the generic Error name.

Go ahead and add other class properties when needed. You can even add methods that are more helpful. Here’s an example:

class CoffeeNotFound extends Error {  
  constructor (message) {
    super(message)
    Error.captureStackTrace(this, this.constructor);

    this.name = this.constructor.name
    this.status = 404
  }

  statusCode() {
    return this.status
  }
}

module.exports = CoffeeNotFound  

This CoffeeNotFound error could be an HTTP error. You may intercept the response and map the error’s status to the HTTP response status.

Throwing Errors

Import the custom error in your app and use it when necessary. Here’s a simple example that just throws the NotEnoughCoffee error:

'use strict'

const NotEnoughCoffee = require('./error')

throw new NotEnoughCoffee('Well, you may need another coffee :)')  

The related error output on your terminal looks like this:

Stack trace when throwing the NotEnoughCoffee error

Custom errors are a good way to help your coworkers and other developers to know what’s wrong with the app configuration.

Enjoy coding & make it rock!

Get Notified on New Future Studio
Content and Platform Updates

Get your weekly push notification about new and trending
Future Studio content and recent platform enhancements

Marcus Pöhls

Marcus is a fullstack JS developer. He’s passionate about the hapi framework for Node.js and loves to build web apps and APIs. Creator of Futureflix and the “learn hapi” learning path.

  • Curtis sepex traction controller 1243 4220 ошибки
  • Curtis 1243 4220 коды ошибок
  • Curtis 1212 контроллер ошибки
  • Cursed ошибка при запуске
  • Currently you have no contract instances to interact with ошибка