Skip to content

Commit bb200b5

Browse files
committed
For #913, add complex error.
1 parent 5852175 commit bb200b5

File tree

6 files changed

+190
-39
lines changed

6 files changed

+190
-39
lines changed

trunk/src/app/srs_app_server.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -557,9 +557,10 @@ void SrsServer::dispose()
557557
#endif
558558
}
559559

560-
int SrsServer::initialize(ISrsServerCycle* cycle_handler)
560+
srs_error_t SrsServer::initialize(ISrsServerCycle* cycle_handler)
561561
{
562562
int ret = ERROR_SUCCESS;
563+
srs_error_t err = srs_success;
563564

564565
// ensure the time is ok.
565566
srs_update_system_time_ms();
@@ -575,15 +576,15 @@ int SrsServer::initialize(ISrsServerCycle* cycle_handler)
575576

576577
handler = cycle_handler;
577578
if(handler && (ret = handler->initialize()) != ERROR_SUCCESS){
578-
return ret;
579+
return srs_error_new(ret, "handler initialize");
579580
}
580581

581582
if ((ret = http_api_mux->initialize()) != ERROR_SUCCESS) {
582-
return ret;
583+
return srs_error_new(ret, "http api initialize");
583584
}
584585

585586
if ((ret = http_server->initialize()) != ERROR_SUCCESS) {
586-
return ret;
587+
return srs_error_new(ret, "http server initialize");
587588
}
588589

589590
http_heartbeat = new SrsHttpHeartbeat();
@@ -593,7 +594,7 @@ int SrsServer::initialize(ISrsServerCycle* cycle_handler)
593594
ingester = new SrsIngester();
594595
#endif
595596

596-
return ret;
597+
return err;
597598
}
598599

599600
int SrsServer::initialize_st()

trunk/src/app/srs_app_server.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ class SrsServer : virtual public ISrsReloadHandler
301301
* initialize server with callback handler.
302302
* @remark user must free the cycle handler.
303303
*/
304-
virtual int initialize(ISrsServerCycle* cycle_handler);
304+
virtual srs_error_t initialize(ISrsServerCycle* cycle_handler);
305305
virtual int initialize_st();
306306
virtual int initialize_signal();
307307
virtual int acquire_pid_file();

trunk/src/core/srs_core.hpp

+4
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,8 @@
115115
#error "only support i386/amd64/x86_64/arm cpu"
116116
#endif
117117

118+
// Error predefined for all modules.
119+
class SrsError;
120+
typedef SrsError* srs_error_t;
121+
118122
#endif

trunk/src/kernel/srs_kernel_error.cpp

+108
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@
2323

2424
#include <srs_kernel_error.hpp>
2525

26+
#include <srs_kernel_log.hpp>
27+
28+
#include <errno.h>
29+
#include <sstream>
30+
using namespace std;
31+
2632
bool srs_is_system_control_error(int error_code)
2733
{
2834
return error_code == ERROR_CONTROL_RTMP_CLOSE
@@ -38,3 +44,105 @@ bool srs_is_client_gracefully_close(int error_code)
3844
|| error_code == ERROR_SOCKET_TIMEOUT;
3945
}
4046

47+
SrsError::SrsError()
48+
{
49+
code = ERROR_SUCCESS;
50+
wrapped = NULL;
51+
cid = rerrno = line = 0;
52+
}
53+
54+
SrsError::~SrsError()
55+
{
56+
}
57+
58+
std::string SrsError::description() {
59+
if (desc.empty()) {
60+
stringstream ss;
61+
ss << "code=" << code;
62+
63+
SrsError* next = this;
64+
while (next) {
65+
ss << " : " << next->msg;
66+
next = next->wrapped;
67+
}
68+
ss << endl;
69+
70+
next = this;
71+
while (next) {
72+
ss << "thread #" << next->cid << ": "
73+
<< next->func << "() [" << next->file << ":" << next->line << "]"
74+
<< "[errno=" << next->rerrno << "]"
75+
<< endl;
76+
next = next->wrapped;
77+
}
78+
79+
desc = ss.str();
80+
}
81+
82+
return desc;
83+
}
84+
85+
SrsError* SrsError::create(const char* func, const char* file, int line, int code, const char* fmt, ...) {
86+
int rerrno = (int)errno;
87+
88+
va_list ap;
89+
va_start(ap, fmt);
90+
static char buffer[4096];
91+
vsnprintf(buffer, sizeof(buffer), fmt, ap);
92+
va_end(ap);
93+
94+
SrsError* err = new SrsError();
95+
96+
err->func = func;
97+
err->file = file;
98+
err->line = line;
99+
err->code = code;
100+
err->rerrno = rerrno;
101+
err->msg = buffer;
102+
err->wrapped = NULL;
103+
if (_srs_context) {
104+
err->cid = _srs_context->get_id();
105+
}
106+
107+
return err;
108+
}
109+
110+
SrsError* SrsError::wrap(const char* func, const char* file, int line, SrsError* v, const char* fmt, ...) {
111+
int rerrno = (int)errno;
112+
113+
va_list ap;
114+
va_start(ap, fmt);
115+
static char buffer[4096];
116+
vsnprintf(buffer, sizeof(buffer), fmt, ap);
117+
va_end(ap);
118+
119+
SrsError* err = new SrsError();
120+
121+
err->func = func;
122+
err->file = file;
123+
err->line = line;
124+
err->code = v->code;
125+
err->rerrno = rerrno;
126+
err->msg = buffer;
127+
err->wrapped = v;
128+
if (_srs_context) {
129+
err->cid = _srs_context->get_id();
130+
}
131+
132+
return err;
133+
}
134+
135+
SrsError* SrsError::success() {
136+
return NULL;
137+
}
138+
139+
string SrsError::description(SrsError* err)
140+
{
141+
return err? err->description() : "Success";
142+
}
143+
144+
int SrsError::error_code(SrsError* err)
145+
{
146+
return err? err->code : ERROR_SUCCESS;
147+
}
148+

trunk/src/kernel/srs_kernel_error.hpp

+38-13
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
#include <srs_core.hpp>
2828

29+
#include <string>
30+
2931
// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213
3032
#ifndef _WIN32
3133
#define ERROR_SUCCESS 0
@@ -330,19 +332,42 @@
330332
extern bool srs_is_system_control_error(int error_code);
331333
extern bool srs_is_client_gracefully_close(int error_code);
332334

333-
/**
334-
@remark: use column copy to generate the new error codes.
335-
01234567890
336-
01234567891
337-
01234567892
338-
01234567893
339-
01234567894
340-
01234567895
341-
01234567896
342-
01234567897
343-
01234567898
344-
01234567899
345-
*/
335+
// Use complex errors, @read https://github.com/ossrs/srs/issues/913
336+
class SrsError
337+
{
338+
private:
339+
int code;
340+
SrsError* wrapped;
341+
std::string msg;
342+
343+
std::string func;
344+
std::string file;
345+
int line;
346+
347+
int cid;
348+
int rerrno;
349+
350+
std::string desc;
351+
private:
352+
SrsError();
353+
public:
354+
virtual ~SrsError();
355+
private:
356+
virtual std::string description();
357+
public:
358+
static SrsError* create(const char* func, const char* file, int line, int code, const char* fmt, ...);
359+
static SrsError* wrap(const char* func, const char* file, int line, SrsError* err, const char* fmt, ...);
360+
static SrsError* success();
361+
static std::string description(SrsError* err);
362+
static int error_code(SrsError* err);
363+
};
364+
365+
// Error helpers, should use these functions to new or wrap an error.
366+
#define srs_success SrsError::success()
367+
#define srs_error_new(ret, fmt, ...) SrsError::create(__FUNCTION__, __FILE__, __LINE__, ret, fmt, ##__VA_ARGS__)
368+
#define srs_error_wrap(err, fmt, ...) SrsError::wrap(__FUNCTION__, __FILE__, __LINE__, err, fmt, ##__VA_ARGS__)
369+
#define srs_error_desc(err) SrsError::description(err)
370+
#define srs_error_code(err) SrsError::error_code(err)
346371

347372
#endif
348373

trunk/src/main/srs_main_server.cpp

+33-20
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ using namespace std;
5050
#include <srs_core_autofree.hpp>
5151

5252
// pre-declare
53-
int run(SrsServer* svr);
53+
srs_error_t run(SrsServer* svr);
5454
int run_master(SrsServer* svr);
5555
void show_macro_features();
5656
string srs_getenv(const char* name);
@@ -182,16 +182,14 @@ int main(int argc, char** argv)
182182
SrsServer* svr = new SrsServer();
183183
SrsAutoFree(SrsServer, svr);
184184

185-
/**
186-
* we do nothing in the constructor of server,
187-
* and use initialize to create members, set hooks for instance the reload handler,
188-
* all initialize will done in this stage.
189-
*/
190-
if ((ret = svr->initialize(NULL)) != ERROR_SUCCESS) {
191-
return ret;
185+
srs_error_t err = run(svr);
186+
if (err != srs_success) {
187+
srs_error("Failed, %s", srs_error_desc(err).c_str());
192188
}
193189

194-
return run(svr);
190+
ret = srs_error_code(err);
191+
srs_freep(err);
192+
return ret;
195193
}
196194

197195
/**
@@ -363,28 +361,40 @@ string srs_getenv(const char* name)
363361
return "";
364362
}
365363

366-
int run(SrsServer* svr)
364+
srs_error_t run(SrsServer* svr)
367365
{
366+
int ret = ERROR_SUCCESS;
367+
srs_error_t err = srs_success;
368+
369+
/**
370+
* we do nothing in the constructor of server,
371+
* and use initialize to create members, set hooks for instance the reload handler,
372+
* all initialize will done in this stage.
373+
*/
374+
if ((err = svr->initialize(NULL)) != srs_success) {
375+
return srs_error_wrap(err, "server initialize");
376+
}
377+
368378
// if not deamon, directly run master.
369379
if (!_srs_config->get_deamon()) {
370-
return run_master(svr);
380+
if ((ret = run_master(svr)) != ERROR_SUCCESS) {
381+
return srs_error_new(ret, "run master");
382+
}
383+
return srs_success;
371384
}
372385

373386
srs_trace("start deamon mode...");
374387

375388
int pid = fork();
376389

377390
if(pid < 0) {
378-
srs_error("create process error. ret=-1"); //ret=0
379-
return -1;
391+
return srs_error_new(-1, "fork father process");
380392
}
381393

382394
// grandpa
383395
if(pid > 0) {
384396
int status = 0;
385-
if(waitpid(pid, &status, 0) == -1) {
386-
srs_error("wait child process error! ret=-1"); //ret=0
387-
}
397+
waitpid(pid, &status, 0);
388398
srs_trace("grandpa process exit.");
389399
exit(0);
390400
}
@@ -393,19 +403,22 @@ int run(SrsServer* svr)
393403
pid = fork();
394404

395405
if(pid < 0) {
396-
srs_error("create process error. ret=0");
397-
return -1;
406+
return srs_error_new(-1, "fork child process");
398407
}
399408

400409
if(pid > 0) {
401-
srs_trace("father process exit. ret=0");
410+
srs_trace("father process exit");
402411
exit(0);
403412
}
404413

405414
// son
406415
srs_trace("son(deamon) process running.");
407416

408-
return run_master(svr);
417+
if ((ret = run_master(svr)) != ERROR_SUCCESS) {
418+
return srs_error_new(ret, "daemon run master");
419+
}
420+
421+
return srs_success;
409422
}
410423

411424
int run_master(SrsServer* svr)

0 commit comments

Comments
 (0)