Server application performing load balancing and monitoring of nodejs applications
Revisão | 2f1dcadd616d53dcd9ff4bba749293c78d12d2e7 (tree) |
---|---|
Hora | 2021-05-07 13:09:38 |
Autor | Vladimir Markin <v.o.markin221@gmai...> |
Commiter | Vladimir Markin |
zero socet data protection
@@ -43,13 +43,13 @@ | ||
43 | 43 | public: |
44 | 44 | file_buffer_t() |
45 | 45 | : _path(get_temporary_path()), _stream(_path, std::fstream::out | std::fstream::in | std::fstream::app | std::fstream::binary), _first_read(true) { |
46 | - | |
46 | + | |
47 | 47 | } |
48 | 48 | |
49 | 49 | ~file_buffer_t(){ |
50 | 50 | try { _stream.close(); } catch (std::exception e) {} |
51 | - try { | |
52 | - std::filesystem::remove(_path); | |
51 | + try { | |
52 | + std::filesystem::remove(_path); | |
53 | 53 | } |
54 | 54 | catch (std::exception e) { |
55 | 55 | fcf::err << "ERROR REMOVE FILE TEMP FILE " << _path.string(); |
@@ -77,9 +77,9 @@ | ||
77 | 77 | } |
78 | 78 | |
79 | 79 | endpoint_t::endpoint_t(const server_configuration_t& a_server_config, size_t a_handler_index) |
80 | - : _slave(a_server_config.slave), | |
81 | - _config(a_server_config.endpoints[a_handler_index]), | |
82 | - _start_group(0), | |
80 | + : _slave(a_server_config.slave), | |
81 | + _config(a_server_config.endpoints[a_handler_index]), | |
82 | + _start_group(0), | |
83 | 83 | _stop(false) { |
84 | 84 | |
85 | 85 | for(size_t i = 0; i < a_server_config.endpoints.size() && i < a_handler_index; ++i){ |
@@ -129,7 +129,7 @@ | ||
129 | 129 | } |
130 | 130 | if (leak_proteced) |
131 | 131 | argv1.push_back("--leak-protected"); |
132 | - | |
132 | + | |
133 | 133 | |
134 | 134 | std::vector<std::string> argv2; |
135 | 135 | argv2.push_back(hc.script); |
@@ -163,19 +163,19 @@ | ||
163 | 163 | |
164 | 164 | std::wstring_convert<std::codecvt_utf8<wchar_t>> conv; |
165 | 165 | std::string node_path = conv.to_bytes(boost::process::search_path("node").wstring()); |
166 | - _subprocesses[hi]->append(node_path.c_str(), | |
166 | + _subprocesses[hi]->append(node_path.c_str(), | |
167 | 167 | argv1, |
168 | 168 | argv2, |
169 | 169 | envv, |
170 | 170 | hc.nodeOptions[procindex], |
171 | - hc.user.c_str(), | |
172 | - hc.password.c_str(), | |
171 | + hc.user.c_str(), | |
172 | + hc.password.c_str(), | |
173 | 173 | hc.dataPorts[procindex*2], |
174 | 174 | hc.dataPorts[procindex*2+1], |
175 | - hc.controlPorts[procindex*2], | |
176 | - hc.controlPorts[procindex*2+1], | |
177 | - hc.startTimeout, | |
178 | - hc.stopTimeout, | |
175 | + hc.controlPorts[procindex*2], | |
176 | + hc.controlPorts[procindex*2+1], | |
177 | + hc.startTimeout, | |
178 | + hc.stopTimeout, | |
179 | 179 | !!leak_proteced); |
180 | 180 | ++procindex; |
181 | 181 |
@@ -199,7 +199,7 @@ | ||
199 | 199 | _socket6->listen(_config.listenQueue); |
200 | 200 | _endpoint_thread6 = std::thread(&endpoint_t::_endpoint_handler, std::ref(*this), _socket6.get()); |
201 | 201 | } |
202 | - | |
202 | + | |
203 | 203 | } |
204 | 204 | |
205 | 205 | void endpoint_t::stop() { |
@@ -325,7 +325,7 @@ | ||
325 | 325 | |
326 | 326 | if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - start_request).count() > max_request_timeout) |
327 | 327 | throw fcf::except::max_request_timeout(a_socket->get_address(), a_socket->get_port()); |
328 | - | |
328 | + | |
329 | 329 | first_buffer_offset += recc; |
330 | 330 | total_size = first_buffer_offset; |
331 | 331 | rec_total_size = first_buffer_offset; |
@@ -371,32 +371,32 @@ | ||
371 | 371 | path_cmp_weigth = 0; |
372 | 372 | break; |
373 | 373 | } else if (width >= 1 && |
374 | - !cur_host_empty && cur_host_iseq && | |
375 | - !cur_path_empty && cur_path_match && | |
374 | + !cur_host_empty && cur_host_iseq && | |
375 | + !cur_path_empty && cur_path_match && | |
376 | 376 | (width != 1 || path_cmp_weigth > cur_path_cmp_width)) { |
377 | 377 | new_handler_index = hi; |
378 | 378 | width = 1; |
379 | 379 | path_cmp_weigth = cur_path_cmp_width; |
380 | 380 | } else if (width > 2 && |
381 | - !cur_host_empty && cur_host_iseq && | |
381 | + !cur_host_empty && cur_host_iseq && | |
382 | 382 | cur_path_empty) { |
383 | 383 | new_handler_index = hi; |
384 | 384 | width = 2; |
385 | 385 | path_cmp_weigth = 0; |
386 | 386 | } else if (width > 3 && |
387 | - cur_host_empty && | |
387 | + cur_host_empty && | |
388 | 388 | !cur_path_empty && cur_path_iseq){ |
389 | 389 | new_handler_index = hi; |
390 | 390 | width = 3; |
391 | 391 | path_cmp_weigth = 0; |
392 | 392 | } else if (width >= 4 && |
393 | - cur_host_empty && | |
393 | + cur_host_empty && | |
394 | 394 | (width != 4 || path_cmp_weigth > cur_path_cmp_width)){ |
395 | 395 | new_handler_index = hi; |
396 | 396 | width = 4; |
397 | 397 | path_cmp_weigth = cur_path_cmp_width; |
398 | 398 | } else if (width > 5 && |
399 | - cur_host_empty && | |
399 | + cur_host_empty && | |
400 | 400 | cur_path_empty){ |
401 | 401 | new_handler_index = hi; |
402 | 402 | width = 5; |
@@ -426,15 +426,24 @@ | ||
426 | 426 | if (!is_big_data) { |
427 | 427 | if (first_buffer_offset < full_pack) |
428 | 428 | residual_buffer.resize(full_pack - first_buffer_offset); |
429 | + bool firstEmpty = true; | |
429 | 430 | while (rec_total_size < full_pack) { |
430 | - rec_total_size += a_socket->recv(&residual_buffer[rec_total_size - first_buffer_offset], full_pack - rec_total_size < MAX_PACK ? full_pack - rec_total_size : MAX_PACK); | |
431 | + size_t size = a_socket->recv(&residual_buffer[rec_total_size - first_buffer_offset], full_pack - rec_total_size < MAX_PACK ? full_pack - rec_total_size : MAX_PACK); | |
432 | + if (!size && !firstEmpty) | |
433 | + throw std::runtime_error("Empty receive data (recv())"); | |
434 | + firstEmpty = !!size; | |
435 | + rec_total_size += size; | |
431 | 436 | if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - start_request).count() > max_request_timeout) |
432 | 437 | throw fcf::except::max_request_timeout_fi(a_socket->get_address(), a_socket->get_port(), request_header_info.host.c_str(), request_header_info.path.c_str()); |
433 | 438 | } |
434 | 439 | } else if (rec_total_size < full_pack) { |
435 | 440 | file_buffer.reset(new file_buffer_t()); |
441 | + bool firstEmpty = true; | |
436 | 442 | while (rec_total_size < full_pack) { |
437 | 443 | size_t size = a_socket->recv(&big_data_buffer[0], full_pack - rec_total_size < MAX_PACK ? full_pack - rec_total_size : MAX_PACK); |
444 | + if (!size && !firstEmpty) | |
445 | + throw std::runtime_error("Empty receive data (recv())"); | |
446 | + firstEmpty = !!size; | |
438 | 447 | rec_total_size += size; |
439 | 448 | file_buffer->write(&big_data_buffer[0], size); |
440 | 449 | if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - start_request).count() > max_request_timeout) |
@@ -464,18 +473,30 @@ | ||
464 | 473 | |
465 | 474 | // send header with data |
466 | 475 | offset = 0; |
467 | - while(offset < first_buffer_offset){ | |
468 | - offset += process_socket->send(&first_buffer[offset], first_buffer_offset - offset); | |
469 | - if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - start_request).count() > max_request_timeout) | |
470 | - throw fcf::except::max_request_timeout_fi(a_socket->get_address(), a_socket->get_port(), request_header_info.host.c_str(), request_header_info.path.c_str()); | |
476 | + { | |
477 | + bool firstEmpty = true; | |
478 | + while(offset < first_buffer_offset){ | |
479 | + size_t size = process_socket->send(&first_buffer[offset], first_buffer_offset - offset); | |
480 | + offset += size; | |
481 | + if (!size && !firstEmpty) | |
482 | + throw std::runtime_error("Empty send data to process (send())"); | |
483 | + firstEmpty = !!size; | |
484 | + if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - start_request).count() > max_request_timeout) | |
485 | + throw fcf::except::max_request_timeout_fi(a_socket->get_address(), a_socket->get_port(), request_header_info.host.c_str(), request_header_info.path.c_str()); | |
486 | + } | |
471 | 487 | } |
472 | 488 | |
473 | 489 | // send residual message to process |
474 | 490 | offset = 0; |
475 | 491 | if (!is_big_data) { |
476 | 492 | //residual_buffer |
493 | + bool firstEmpty = true; | |
477 | 494 | while((offset + first_buffer_offset) < full_pack) { |
478 | - offset += process_socket->send(&residual_buffer[offset], (full_pack - first_buffer_offset) - offset); | |
495 | + size_t size = process_socket->send(&residual_buffer[offset], (full_pack - first_buffer_offset) - offset); | |
496 | + offset += size; | |
497 | + if (!size && !firstEmpty) | |
498 | + throw std::runtime_error("Empty send data to process (send())"); | |
499 | + firstEmpty = !!size; | |
479 | 500 | if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - start_request).count() > max_request_timeout) |
480 | 501 | throw fcf::except::max_request_timeout_fi(a_socket->get_address(), a_socket->get_port(), request_header_info.host.c_str(), request_header_info.path.c_str()); |
481 | 502 | } |
@@ -485,8 +506,13 @@ | ||
485 | 506 | file_buffer->read(&big_data_buffer[0], pack_size); |
486 | 507 | |
487 | 508 | size_t part_size = 0; |
509 | + bool firstEmpty = true; | |
488 | 510 | while(part_size < pack_size) { |
489 | - part_size += process_socket->send(&big_data_buffer[part_size], pack_size - part_size); | |
511 | + size_t size = process_socket->send(&big_data_buffer[part_size], pack_size - part_size); | |
512 | + part_size += size; | |
513 | + if (!size && !firstEmpty) | |
514 | + throw std::runtime_error("Empty send data to process (send())"); | |
515 | + firstEmpty = !!size; | |
490 | 516 | if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - start_request).count() > max_request_timeout) |
491 | 517 | throw fcf::except::max_request_timeout_fi(a_socket->get_address(), a_socket->get_port(), request_header_info.host.c_str(), request_header_info.path.c_str()); |
492 | 518 | } |
@@ -523,7 +549,8 @@ | ||
523 | 549 | |
524 | 550 | // send header with data to client |
525 | 551 | full_pack = response_header_info.content_length + response_header_info.header_end + 4; |
526 | - offset = 0; | |
552 | + offset = 0; | |
553 | + bool firstEmpty = true; | |
527 | 554 | while (offset < total_size) { |
528 | 555 | if (!sps->active) { |
529 | 556 | _buffered_forwarding(&first_buffer[offset], |
@@ -539,13 +566,18 @@ | ||
539 | 566 | completed = true; |
540 | 567 | break; |
541 | 568 | } |
542 | - offset += a_socket->send(&first_buffer[offset], total_size - offset > MAX_PACK ? MAX_PACK : (unsigned int)(total_size - offset)); | |
569 | + size_t size = a_socket->send(&first_buffer[offset], total_size - offset > MAX_PACK ? MAX_PACK : (unsigned int)(total_size - offset)); | |
570 | + offset += size; | |
571 | + if (!size && !firstEmpty) | |
572 | + throw std::runtime_error("Empty send data to client (send())"); | |
573 | + firstEmpty = !!size; | |
543 | 574 | if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - start_response).count() > max_response_timeout) |
544 | 575 | throw fcf::except::max_response_timeout_fi(a_socket->get_address(), a_socket->get_port(), request_header_info.host.c_str(), request_header_info.path.c_str()); |
545 | 576 | } |
546 | 577 | |
547 | 578 | // resend data to client |
548 | 579 | if (!completed) { |
580 | + bool firstEmpty = true; | |
549 | 581 | while(total_size < full_pack) { |
550 | 582 | if (!sps->active) { |
551 | 583 | _buffered_forwarding(&first_buffer[0], |
@@ -563,6 +595,9 @@ | ||
563 | 595 | } |
564 | 596 | |
565 | 597 | offset = process_socket->recv(&first_buffer[0], MAX_PACK); |
598 | + if (!offset && !firstEmpty) | |
599 | + throw std::runtime_error("Empty receive data from process (send())"); | |
600 | + firstEmpty = !!offset; | |
566 | 601 | if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - start_response).count() > max_response_timeout) |
567 | 602 | throw fcf::except::max_response_timeout_fi(a_socket->get_address(), a_socket->get_port(), request_header_info.host.c_str(), request_header_info.path.c_str()); |
568 | 603 |
@@ -582,10 +617,17 @@ | ||
582 | 617 | } |
583 | 618 | |
584 | 619 | int sendc = 0; |
585 | - while(sendc < offset){ | |
586 | - sendc += a_socket->send(&first_buffer[sendc], offset - sendc); | |
587 | - if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - start_response).count() > max_response_timeout) | |
588 | - throw fcf::except::max_response_timeout_fi(a_socket->get_address(), a_socket->get_port(), request_header_info.host.c_str(), request_header_info.path.c_str()); | |
620 | + { | |
621 | + bool firstEmpty = true; | |
622 | + while(sendc < offset){ | |
623 | + bool size = a_socket->send(&first_buffer[sendc], offset - sendc); | |
624 | + sendc += size; | |
625 | + if (!size && !firstEmpty) | |
626 | + throw std::runtime_error("Empty send data to client (send())"); | |
627 | + firstEmpty = !!size; | |
628 | + if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - start_response).count() > max_response_timeout) | |
629 | + throw fcf::except::max_response_timeout_fi(a_socket->get_address(), a_socket->get_port(), request_header_info.host.c_str(), request_header_info.path.c_str()); | |
630 | + } | |
589 | 631 | } |
590 | 632 | |
591 | 633 | total_size += offset; |
@@ -614,27 +656,48 @@ | ||
614 | 656 | |
615 | 657 | // send header with data |
616 | 658 | offset = 0; |
617 | - while(offset < total_size){ | |
618 | - offset += process_socket->send(&first_buffer[offset], total_size - offset > MAX_PACK ? MAX_PACK : (unsigned int)(total_size - offset)); | |
619 | - if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - start_request).count() > max_request_timeout) | |
620 | - throw fcf::except::max_request_timeout_fi(a_socket->get_address(), a_socket->get_port(), request_header_info.host.c_str(), request_header_info.path.c_str()); | |
659 | + { | |
660 | + bool firstEmpty = true; | |
661 | + while(offset < total_size){ | |
662 | + size_t size = process_socket->send(&first_buffer[offset], total_size - offset > MAX_PACK ? MAX_PACK : (unsigned int)(total_size - offset)); | |
663 | + offset += size; | |
664 | + if (!size && !firstEmpty) | |
665 | + throw std::runtime_error("Empty send data to process (send())"); | |
666 | + firstEmpty = !!size; | |
667 | + | |
668 | + if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - start_request).count() > max_request_timeout) | |
669 | + throw fcf::except::max_request_timeout_fi(a_socket->get_address(), a_socket->get_port(), request_header_info.host.c_str(), request_header_info.path.c_str()); | |
670 | + } | |
621 | 671 | } |
622 | 672 | |
623 | 673 | // resend data to process |
624 | 674 | full_pack = request_header_info.content_length + request_header_info.header_end + 4; |
625 | - while(total_size < full_pack){ | |
626 | - offset = a_socket->recv(&first_buffer[0], MAX_PACK); | |
627 | - if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - start_request).count() > max_request_timeout) | |
628 | - throw fcf::except::max_request_timeout_fi(a_socket->get_address(), a_socket->get_port(), request_header_info.host.c_str(), request_header_info.path.c_str()); | |
629 | - | |
630 | - int sendc = 0; | |
631 | - while(sendc < offset){ | |
632 | - sendc += process_socket->send(&first_buffer[sendc], offset - sendc); | |
675 | + { | |
676 | + bool firstEmpty = true; | |
677 | + while(total_size < full_pack){ | |
678 | + offset = a_socket->recv(&first_buffer[0], MAX_PACK); | |
679 | + if (!offset && !firstEmpty) | |
680 | + throw std::runtime_error("Empty receive data from client (recv())"); | |
681 | + firstEmpty = !!offset; | |
633 | 682 | if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - start_request).count() > max_request_timeout) |
634 | 683 | throw fcf::except::max_request_timeout_fi(a_socket->get_address(), a_socket->get_port(), request_header_info.host.c_str(), request_header_info.path.c_str()); |
684 | + | |
685 | + int sendc = 0; | |
686 | + { | |
687 | + bool firstEmpty = true; | |
688 | + while(sendc < offset){ | |
689 | + size_t size = process_socket->send(&first_buffer[sendc], offset - sendc); | |
690 | + sendc += size; | |
691 | + if (!size && !firstEmpty) | |
692 | + throw std::runtime_error("Empty send data to process (send())"); | |
693 | + firstEmpty = !!size; | |
694 | + if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - start_request).count() > max_request_timeout) | |
695 | + throw fcf::except::max_request_timeout_fi(a_socket->get_address(), a_socket->get_port(), request_header_info.host.c_str(), request_header_info.path.c_str()); | |
696 | + } | |
697 | + } | |
698 | + | |
699 | + total_size += offset; | |
635 | 700 | } |
636 | - | |
637 | - total_size += offset; | |
638 | 701 | } |
639 | 702 | |
640 | 703 | // get response |
@@ -665,30 +728,50 @@ | ||
665 | 728 | } |
666 | 729 | |
667 | 730 | // send header with data to client |
668 | - offset = 0; | |
669 | - while(offset < total_size){ | |
670 | - offset += a_socket->send(&first_buffer[offset], total_size - offset > MAX_PACK ? MAX_PACK : (unsigned int)(total_size - offset)); | |
671 | - if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - start_response).count() > max_response_timeout) | |
672 | - throw fcf::except::max_response_timeout_fi(a_socket->get_address(), a_socket->get_port(), request_header_info.host.c_str(), request_header_info.path.c_str()); | |
731 | + offset = 0; | |
732 | + { | |
733 | + bool firstEmpty = true; | |
734 | + while(offset < total_size){ | |
735 | + size_t size = a_socket->send(&first_buffer[offset], total_size - offset > MAX_PACK ? MAX_PACK : (unsigned int)(total_size - offset)); | |
736 | + offset += size; | |
737 | + if (!size && !firstEmpty) | |
738 | + throw std::runtime_error("Empty sending data to client(send())"); | |
739 | + firstEmpty = !!size; | |
740 | + | |
741 | + if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - start_response).count() > max_response_timeout) | |
742 | + throw fcf::except::max_response_timeout_fi(a_socket->get_address(), a_socket->get_port(), request_header_info.host.c_str(), request_header_info.path.c_str()); | |
743 | + } | |
673 | 744 | } |
674 | 745 | |
675 | 746 | // resend data to client |
676 | 747 | full_pack = response_header_info.content_length + response_header_info.header_end + 4; |
677 | - while(total_size < full_pack){ | |
678 | - offset = process_socket->recv(&first_buffer[0], MAX_PACK); | |
679 | - if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - start_request).count() > max_response_timeout) | |
680 | - throw fcf::except::max_response_timeout_fi(a_socket->get_address(), a_socket->get_port(), request_header_info.host.c_str(), request_header_info.path.c_str()); | |
681 | - | |
682 | - int sendc = 0; | |
683 | - while(sendc < offset){ | |
684 | - sendc += a_socket->send(&first_buffer[sendc], offset - sendc); | |
748 | + { | |
749 | + bool firstEmpty = true; | |
750 | + while(total_size < full_pack){ | |
751 | + offset = process_socket->recv(&first_buffer[0], MAX_PACK); | |
752 | + if (!offset && !firstEmpty) | |
753 | + throw std::runtime_error("Empty receive data from process(recv())"); | |
754 | + firstEmpty = !!offset; | |
685 | 755 | if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - start_request).count() > max_response_timeout) |
686 | 756 | throw fcf::except::max_response_timeout_fi(a_socket->get_address(), a_socket->get_port(), request_header_info.host.c_str(), request_header_info.path.c_str()); |
687 | - } | |
688 | 757 | |
689 | - total_size += offset; | |
758 | + int sendc = 0; | |
759 | + { | |
760 | + bool firstEmpty = true; | |
761 | + while(sendc < offset){ | |
762 | + size_t size = a_socket->send(&first_buffer[sendc], offset - sendc); | |
763 | + sendc += size; | |
764 | + if (!size && !firstEmpty) | |
765 | + throw std::runtime_error("Empty receive data (recv())"); | |
766 | + firstEmpty = !!size; | |
767 | + if (std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now() - start_request).count() > max_response_timeout) | |
768 | + throw fcf::except::max_response_timeout_fi(a_socket->get_address(), a_socket->get_port(), request_header_info.host.c_str(), request_header_info.path.c_str()); | |
769 | + } | |
770 | + } | |
771 | + | |
772 | + total_size += offset; | |
773 | + } | |
690 | 774 | } |
691 | - | |
692 | 775 | } |
693 | 776 | |
694 | 777 | if (response_header_info.connection != "keep-alive") |
@@ -707,7 +790,7 @@ | ||
707 | 790 | } |
708 | 791 | |
709 | 792 | } catch(const std::exception& e) { |
710 | - fcf::trc << "IP:" << a_socket->get_address() << " PORT:" << a_socket->get_port() << " " << e.what(); | |
793 | + fcf::trc << "IP:" << a_socket->get_address() << " PORT:" << a_socket->get_port() << " " << e.what(); | |
711 | 794 | } catch (...) { |
712 | 795 | fcf::trc << "Unknown Exception in handler"; |
713 | 796 | } |
@@ -62,9 +62,11 @@ | ||
62 | 62 | try { |
63 | 63 | client.reset(_socket->accept()); |
64 | 64 | rc = client->recv(&buffer[0], sizeof(buffer)); |
65 | - } catch(const std::exception& e){ | |
65 | + if (!rc) | |
66 | + throw new std::runtime_error("Empty inner command"); | |
67 | + } catch(const std::exception& e) { | |
66 | 68 | lock.lock(); |
67 | - throw e; | |
69 | + throw std::runtime_error(e.what()); | |
68 | 70 | } |
69 | 71 | lock.lock(); |
70 | 72 | if (_stop) |