-
Notifications
You must be signed in to change notification settings - Fork 4
/
index.js
133 lines (118 loc) · 5.18 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
const createMetadata = require('grpc-create-metadata')
module.exports = createGRPCError
/**
* Utility function that creates an Error suitable for gRPC responses.
* See tests for all examples
* @param {String|Number|Error|Object} [message] If <code>String</code> the error message
* If <code>Number</code> the error code
* If instanceof <code>Error</code>, the error to source data from. We still create a new
* <code>Error</code> instance, copy data from the passed error and assign / merge the rest
* of arguments. This can be used to mege metadata of existing error with
* additional metadata.
* If <code>Object</code>, assumed to be metadata, either plain object representation
* or actual <code>grpc.Metadata</code> instance. We use
* <code>grpc-create-metadata</code> module to create metadata for the
* return value.
* @param {Number|Object} [code] If <code>Number</code> the error code
* If <code>Object</code>, assumed to be metadata, either plain object representation
* or actual <code>grpc.Metadata</code> instance. We use
* <code>grpc-create-metadata</code> module to create metadata for the
* return value.
* @param {Object} [metadata] The error metadata. Either plain object representation or actual
* <code>grpc.Metadata</code> instance. We use <code>grpc-create-metadata</code>
* module to create metadata for the return value.
* @return {Error} The new Error
* @example <caption>Using standard grpc status code</caption>
* const grpc = require('grpc')
* const createGRPCError = require('create-grpc-error')
* const err = createGRPCError('Ouch!', grpc.status.INVALID_ARGUMENT)
*
* @example <caption>Custom error with metadata</caption>
* const createGRPCError = require('create-grpc-error')
* const err = createGRPCError('Boom', 2000, { ERROR_CODE: 'INVALID_TOKEN' })
* console.log(err.message) // 'Boom'
* console.log(err.code) // 2000
* console.log(err.metadata instanceof grpc.Metadata) // true
* console.log(err.metadata.getMap()) // { error_code: 'INVALID_TOKEN' }
*
* @example <caption>Source from error and merge metadatas</caption>
* const createGRPCError = require('create-grpc-error')
*
* const existingError = new Error('Boom')
* existingError.metadata = new grpc.Metadata()
* existingError.metadata.add('foo', 'bar')
*
* const err = createGRPCError(existingError, 2000, { ERROR_CODE: 'INVALID_TOKEN' })
* console.log(err.message) // 'Boom'
* console.log(err.code) // 2000
* console.log(err.metadata instanceof grpc.Metadata) // true
* console.log(err.metadata.getMap()) // { foo: 'bar', error_code: 'INVALID_TOKEN' }
*/
function createGRPCError (message, code, metadata) {
const err = new Error()
return applyCreate(err, message, code, metadata)
}
/**
* Actual function that does all the work.
* Same as createGRPCError but applies cretion to the existing error.
* @param {Error} err The error to apply creation to
* @param {String|Number|Error|Object} message See <code>createGRPCError</code> description
* @param {Number|Object} code See <code>createGRPCError</code> description
* @param {Object} metadata See <code>createGRPCError</code> description
* @return {Error} See <code>createGRPCError</code> description
*/
function applyCreate (err, message, code, metadata) {
if (err instanceof Error === false) {
throw new Error('Source error must be an instance of Error')
}
if (message instanceof Error) {
err.message = message.message.toString()
if (typeof message.code === 'number') {
err.code = message.code
}
if (typeof message.metadata === 'object') {
err.metadata = createMetadata(message.metadata)
}
}
const isMsgMD = message instanceof Error
if (message && typeof message === 'object' && !isMsgMD) {
metadata = message
message = ''
code = null
}
if (typeof message === 'number') {
metadata = code
code = message
message = ''
}
if (code && typeof code === 'object') {
metadata = code
code = null
}
if (!metadata) {
metadata = null
}
if (typeof message === 'string') {
err.message = message
}
if (typeof code === 'number') {
err.code = code
}
if (metadata && typeof metadata === 'object') {
if (err.metadata) {
const existingMeta = err.metadata && typeof err.metadata.getMap === 'function'
? err.metadata.getMap()
: null
const md = typeof metadata.getMap === 'function'
? metadata.getMap()
: metadata
if (existingMeta || md) {
err.metadata = createMetadata(Object.assign({}, existingMeta || {}, md || {}))
}
} else {
err.metadata = createMetadata(metadata)
}
}
return err
}
createGRPCError.applyCreate = applyCreate