metacall / faas

Reimplementation of MetaCall FaaS platform written in TypeScript.
https://dashboard.metacall.io
Apache License 2.0
13 stars 20 forks source link

Bug: The local server goes down with bad requests #64

Open Mostafa-wael opened 2 months ago

Mostafa-wael commented 2 months ago

Overview

When you send a buggy/bad request to the FaaS, it goes down.

Env

Steps to reproduce:

Expected output:

Actual Output:

Screenshots:

Logs:

<ref 1> Error: connect ECONNREFUSED 127.0.0.1:9000 at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1494:16) { errno: -111, code: 'ECONNREFUSED', syscall: 'connect', address: '127.0.0.1', port: 9000, config: { url: 'http://localhost:9000/api/inspect', method: 'get', headers: { Accept: 'application/json, text/plain, /', Authorization: 'jwt ', 'User-Agent': 'axios/0.21.4' }, transformRequest: [ [Function: transformRequest] ], transformResponse: [ [Function: transformResponse] ], timeout: 0, adapter: [Function: httpAdapter], xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, maxBodyLength: -1, validateStatus: [Function: validateStatus], transitional: { silentJSONParsing: true, forcedJSONParsing: true, clarifyTimeoutError: false }, data: undefined }, request: <ref 3> Writable { _writableState: WritableState { objectMode: false, highWaterMark: 16384, finalCalled: false, needDrain: false, ending: false, ended: false, finished: false, destroyed: false, decodeStrings: true, defaultEncoding: 'utf8', length: 0, writing: false, corked: 0, sync: true, bufferProcessing: false, onwrite: [Function: bound onwrite], writecb: null, writelen: 0, afterWriteTickInfo: null, buffered: [], bufferedIndex: 0, allBuffers: true, allNoop: true, pendingcb: 0, constructed: true, prefinished: false, errorEmitted: false, emitClose: true, autoDestroy: true, errored: null, closed: false, closeEmitted: false,

},
_events: [Object: null prototype] {
  response: [Function: handleResponse],
  error: [Function: handleRequestError]
},
_eventsCount: 2,
_maxListeners: undefined,
_options: {
  maxRedirects: 21,
  maxBodyLength: 10485760,
  protocol: 'http:',
  path: '/api/inspect',
  method: 'GET',
  headers: {
    Accept: 'application/json, text/plain, */*',
    Authorization: 'jwt ',
    'User-Agent': 'axios/0.21.4'
  },
  agent: undefined,
  agents: { http: undefined, https: undefined },
  auth: undefined,
  hostname: 'localhost',
  port: '9000',
  nativeProtocols: {
    'http:': {
      _connectionListener: [Function: connectionListener],
      METHODS: [
        'ACL',         'BIND',       'CHECKOUT',
        'CONNECT',     'COPY',       'DELETE',
        'GET',         'HEAD',       'LINK',
        'LOCK',        'M-SEARCH',   'MERGE',
        'MKACTIVITY',  'MKCALENDAR', 'MKCOL',
        'MOVE',        'NOTIFY',     'OPTIONS',
        'PATCH',       'POST',       'PROPFIND',
        'PROPPATCH',   'PURGE',      'PUT',
        'REBIND',      'REPORT',     'SEARCH',
        'SOURCE',      'SUBSCRIBE',  'TRACE',
        'UNBIND',      'UNLINK',     'UNLOCK',
        'UNSUBSCRIBE'
      ],
      STATUS_CODES: {
        '100': 'Continue',
        '101': 'Switching Protocols',
        '102': 'Processing',
        '103': 'Early Hints',
        '200': 'OK',
        '201': 'Created',
        '202': 'Accepted',
        '203': 'Non-Authoritative Information',
        '204': 'No Content',
        '205': 'Reset Content',
        '206': 'Partial Content',
        '207': 'Multi-Status',
        '208': 'Already Reported',
        '226': 'IM Used',
        '300': 'Multiple Choices',
        '301': 'Moved Permanently',
        '302': 'Found',
        '303': 'See Other',
        '304': 'Not Modified',
        '305': 'Use Proxy',
        '307': 'Temporary Redirect',
        '308': 'Permanent Redirect',
        '400': 'Bad Request',
        '401': 'Unauthorized',
        '402': 'Payment Required',
        '403': 'Forbidden',
        '404': 'Not Found',
        '405': 'Method Not Allowed',
        '406': 'Not Acceptable',
        '407': 'Proxy Authentication Required',
        '408': 'Request Timeout',
        '409': 'Conflict',
        '410': 'Gone',
        '411': 'Length Required',
        '412': 'Precondition Failed',
        '413': 'Payload Too Large',
        '414': 'URI Too Long',
        '415': 'Unsupported Media Type',
        '416': 'Range Not Satisfiable',
        '417': 'Expectation Failed',
        '418': "I'm a Teapot",
        '421': 'Misdirected Request',
        '422': 'Unprocessable Entity',
        '423': 'Locked',
        '424': 'Failed Dependency',
        '425': 'Too Early',
        '426': 'Upgrade Required',
        '428': 'Precondition Required',
        '429': 'Too Many Requests',
        '431': 'Request Header Fields Too Large',
        '451': 'Unavailable For Legal Reasons',
        '500': 'Internal Server Error',
        '501': 'Not Implemented',
        '502': 'Bad Gateway',
        '503': 'Service Unavailable',
        '504': 'Gateway Timeout',
        '505': 'HTTP Version Not Supported',
        '506': 'Variant Also Negotiates',
        '507': 'Insufficient Storage',
        '508': 'Loop Detected',
        '509': 'Bandwidth Limit Exceeded',
        '510': 'Not Extended',
        '511': 'Network Authentication Required'
      },
      Agent: [Function: Agent] { defaultMaxSockets: Infinity },
      ClientRequest: [Function: ClientRequest],
      IncomingMessage: [Function: IncomingMessage],
      OutgoingMessage: [Function: OutgoingMessage],
      Server: [Function: Server],
      ServerResponse: [Function: ServerResponse],
      createServer: [Function: createServer],
      validateHeaderName: [Function: __node_internal_],
      validateHeaderValue: [Function: __node_internal_],
      get: [Function: get],
      request: [Function: request],
      setMaxIdleHTTPParsers: [Function: setMaxIdleHTTPParsers],
      maxHeaderSize: [Getter],
      globalAgent: [Getter/Setter]
    },
    'https:': {
      Agent: [Function: Agent],
      globalAgent: Agent {
        _events: [Object: null prototype],
        _eventsCount: 2,
        _maxListeners: undefined,
        defaultPort: 443,
        protocol: 'https:',
        options: [Object: null prototype],
        requests: [Object: null prototype] {},
        sockets: [Object: null prototype] {},
        freeSockets: [Object: null prototype] {},
        keepAliveMsecs: 1000,
        keepAlive: true,
        maxSockets: Infinity,
        maxFreeSockets: 256,
        scheduling: 'lifo',
        maxTotalSockets: Infinity,
        totalSocketCount: 0,
        maxCachedSessions: 100,
        _sessionCache: [Object],
        [Symbol(kCapture)]: false
      },
      Server: [Function: Server],
      createServer: [Function: createServer],
      get: [Function: get],
      request: [Function: request]
    }
  },
  pathname: '/api/inspect'
},
_ended: true,
_ending: true,
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 0,
_requestBodyBuffers: [],
_onNativeResponse: [Function (anonymous)],
_currentRequest: <ref *2> ClientRequest {
  _events: [Object: null prototype] {
    response: [Function: bound onceWrapper] {
      listener: [Function (anonymous)]
    },
    abort: [Function (anonymous)],
    aborted: [Function (anonymous)],
    connect: [Function (anonymous)],
    error: [Function (anonymous)],
    socket: [Function (anonymous)],
    timeout: [Function (anonymous)]
  },
  _eventsCount: 7,
  _maxListeners: undefined,
  outputData: [],
  outputSize: 0,
  writable: true,
  destroyed: false,
  _last: true,
  chunkedEncoding: false,
  shouldKeepAlive: true,
  maxRequestsOnConnectionReached: false,
  _defaultKeepAlive: true,
  useChunkedEncodingByDefault: false,
  sendDate: false,
  _removedConnection: false,
  _removedContLen: false,
  _removedTE: false,
  strictContentLength: false,
  _contentLength: 0,
  _hasBody: true,
  _trailer: '',
  finished: true,
  _headerSent: true,
  _closed: false,
  socket: Socket {
    connecting: false,
    _hadError: true,
    _parent: null,
    _host: 'localhost',
    _closeAfterHandlingError: false,
    _readableState: ReadableState {
      objectMode: false,
      highWaterMark: 16384,
      buffer: BufferList { head: null, tail: null, length: 0 },
      length: 0,
      pipes: [],
      flowing: true,
      ended: false,
      endEmitted: false,
      reading: true,
      constructed: true,
      sync: false,
      needReadable: true,
      emittedReadable: false,
      readableListening: false,
      resumeScheduled: false,
      errorEmitted: true,
      emitClose: false,
      autoDestroy: true,
      destroyed: true,
      errored: [Circular *1],
      closed: true,
      closeEmitted: true,
      defaultEncoding: 'utf8',
      awaitDrainWriters: null,
      multiAwaitDrain: false,
      readingMore: false,
      dataEmitted: false,
      decoder: null,
      encoding: null,
      [Symbol(kPaused)]: false
    },
    _events: [Object: null prototype] {
      end: [Function: onReadableStreamEnd],
      connect: [ [Function], [Function], [Function] ],
      free: [Function: onFree],
      close: [
        [Function: onClose],
        [Function: socketCloseListener],
        [Function]
      ],
      timeout: [ [Function: onTimeout], [Function] ],
      agentRemove: [Function: onRemove],
      error: [Function: socketErrorListener],
      drain: [Function: ondrain]
    },
    _eventsCount: 8,
    _maxListeners: undefined,
    _writableState: WritableState {
      objectMode: false,
      highWaterMark: 16384,
      finalCalled: false,
      needDrain: false,
      ending: false,
      ended: false,
      finished: false,
      destroyed: true,
      decodeStrings: false,
      defaultEncoding: 'utf8',
      length: 165,
      writing: true,
      corked: 0,
      sync: false,
      bufferProcessing: false,
      onwrite: [Function: bound onwrite],
      writecb: [Function: bound onFinish],
      writelen: 165,
      afterWriteTickInfo: null,
      buffered: [],
      bufferedIndex: 0,
      allBuffers: true,
      allNoop: true,
      pendingcb: 1,
      constructed: true,
      prefinished: false,
      errorEmitted: true,
      emitClose: false,
      autoDestroy: true,
      errored: [Circular *1],
      closed: true,
      closeEmitted: true,
      [Symbol(kOnFinished)]: []
    },
    allowHalfOpen: false,
    _sockname: null,
    _pendingData: 'GET /api/inspect HTTP/1.1\r\n' +
      'Accept: application/json, text/plain, */*\r\n' +
      'Authorization: jwt \r\n' +
      'User-Agent: axios/0.21.4\r\n' +
      'Host: localhost:9000\r\n' +
      'Connection: keep-alive\r\n' +
      '\r\n',
    _pendingEncoding: 'latin1',
    server: null,
    _server: null,
    timeout: 5000,
    parser: null,
    _httpMessage: [Circular *2],
    [Symbol(async_id_symbol)]: 2810,
    [Symbol(kHandle)]: null,
    [Symbol(lastWriteQueueSize)]: 0,
    [Symbol(timeout)]: Timeout {
      _idleTimeout: -1,
      _idlePrev: null,
      _idleNext: null,
      _idleStart: 595696,
      _onTimeout: null,
      _timerArgs: undefined,
      _repeat: null,
      _destroyed: true,
      [Symbol(refed)]: false,
      [Symbol(kHasPrimitive)]: false,
      [Symbol(asyncId)]: 2809,
      [Symbol(triggerId)]: 0
    },
    [Symbol(kBuffer)]: null,
    [Symbol(kBufferCb)]: null,
    [Symbol(kBufferGen)]: null,
    [Symbol(kCapture)]: false,
    [Symbol(kSetNoDelay)]: true,
    [Symbol(kSetKeepAlive)]: true,
    [Symbol(kSetKeepAliveInitialDelay)]: 1,
    [Symbol(kBytesRead)]: 0,
    [Symbol(kBytesWritten)]: 0
  },
  _header: 'GET /api/inspect HTTP/1.1\r\n' +
    'Accept: application/json, text/plain, */*\r\n' +
    'Authorization: jwt \r\n' +
    'User-Agent: axios/0.21.4\r\n' +
    'Host: localhost:9000\r\n' +
    'Connection: keep-alive\r\n' +
    '\r\n',
  _keepAliveTimeout: 0,
  _onPendingData: [Function: nop],
  agent: Agent {
    _events: [Object: null prototype] {
      free: [Function (anonymous)],
      newListener: [Function: maybeEnableKeylog]
    },
    _eventsCount: 2,
    _maxListeners: undefined,
    defaultPort: 80,
    protocol: 'http:',
    options: [Object: null prototype] {
      keepAlive: true,
      scheduling: 'lifo',
      timeout: 5000,
      noDelay: true,
      path: null
    },
    requests: [Object: null prototype] {},
    sockets: [Object: null prototype] { 'localhost:9000:': [ [Socket] ] },
    freeSockets: [Object: null prototype] {},
    keepAliveMsecs: 1000,
    keepAlive: true,
    maxSockets: Infinity,
    maxFreeSockets: 256,
    scheduling: 'lifo',
    maxTotalSockets: Infinity,
    totalSocketCount: 1,
    [Symbol(kCapture)]: false
  },
  socketPath: undefined,
  method: 'GET',
  maxHeaderSize: undefined,
  insecureHTTPParser: undefined,
  joinDuplicateHeaders: undefined,
  path: '/api/inspect',
  _ended: false,
  res: null,
  aborted: false,
  timeoutCb: [Function: emitRequestTimeout],
  upgradeOrConnect: false,
  parser: null,
  maxHeadersCount: null,
  reusedSocket: false,
  host: 'localhost',
  protocol: 'http:',
  _redirectable: [Circular *3],
  [Symbol(kCapture)]: false,
  [Symbol(kBytesWritten)]: 0,
  [Symbol(kEndCalled)]: true,
  [Symbol(kNeedDrain)]: false,
  [Symbol(corked)]: 0,
  [Symbol(kOutHeaders)]: [Object: null prototype] {
    accept: [ 'Accept', 'application/json, text/plain, */*' ],
    authorization: [ 'Authorization', 'jwt ' ],
    'user-agent': [ 'User-Agent', 'axios/0.21.4' ],
    host: [ 'Host', 'localhost:9000' ]
  },
  [Symbol(errored)]: null,
  [Symbol(kUniqueHeaders)]: null
},
_currentUrl: 'http://localhost:9000/api/inspect',
[Symbol(kCapture)]: false

}, response: undefined, isAxiosError: true, toJSON: [Function: toJSON] }

Node.js v19.7.0